Skip to content

Commit

Permalink
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/jgarzik/libata-dev

* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev:
  [PATCH] pata-qdi: fix le32 in data_xfer
  [libata] sata_promise: add PCI ID
  [PATCH] libata: return sense data in HDIO_DRIVE_CMD ioctl
  [PATCH] libata: Don't believe bogus claims in the older PIO mode register
  • Loading branch information
Linus Torvalds committed Oct 11, 2006
2 parents 60ca975 + 701328a commit 6bf1f75
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 9 deletions.
6 changes: 5 additions & 1 deletion drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -870,7 +870,11 @@ static unsigned int ata_id_xfermask(const u16 *id)
* the PIO timing number for the maximum. Turn it into
* a mask.
*/
pio_mask = (2 << (id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ;
u8 mode = id[ATA_ID_OLD_PIO_MODES] & 0xFF;
if (mode < 5) /* Valid PIO range */
pio_mask = (2 << mode) - 1;
else
pio_mask = 1;

/* But wait.. there's more. Design your standards by
* committee and you too can get a free iordy field to
Expand Down
46 changes: 39 additions & 7 deletions drivers/ata/libata-scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,17 +164,21 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
{
int rc = 0;
u8 scsi_cmd[MAX_COMMAND_SIZE];
u8 args[4], *argbuf = NULL;
u8 args[4], *argbuf = NULL, *sensebuf = NULL;
int argsize = 0;
struct scsi_sense_hdr sshdr;
enum dma_data_direction data_dir;
int cmd_result;

if (arg == NULL)
return -EINVAL;

if (copy_from_user(args, arg, sizeof(args)))
return -EFAULT;

sensebuf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO);
if (!sensebuf)
return -ENOMEM;

memset(scsi_cmd, 0, sizeof(scsi_cmd));

if (args[3]) {
Expand All @@ -191,7 +195,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
data_dir = DMA_FROM_DEVICE;
} else {
scsi_cmd[1] = (3 << 1); /* Non-data */
/* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
scsi_cmd[2] = 0x20; /* cc but no off.line or data xfer */
data_dir = DMA_NONE;
}

Expand All @@ -210,18 +214,46 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)

/* Good values for timeout and retries? Values below
from scsi_ioctl_send_command() for default case... */
if (scsi_execute_req(scsidev, scsi_cmd, data_dir, argbuf, argsize,
&sshdr, (10*HZ), 5)) {
cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize,
sensebuf, (10*HZ), 5, 0);

if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
u8 *desc = sensebuf + 8;
cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */

/* If we set cc then ATA pass-through will cause a
* check condition even if no error. Filter that. */
if (cmd_result & SAM_STAT_CHECK_CONDITION) {
struct scsi_sense_hdr sshdr;
scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE,
&sshdr);
if (sshdr.sense_key==0 &&
sshdr.asc==0 && sshdr.ascq==0)
cmd_result &= ~SAM_STAT_CHECK_CONDITION;
}

/* Send userspace a few ATA registers (same as drivers/ide) */
if (sensebuf[0] == 0x72 && /* format is "descriptor" */
desc[0] == 0x09 ) { /* code is "ATA Descriptor" */
args[0] = desc[13]; /* status */
args[1] = desc[3]; /* error */
args[2] = desc[5]; /* sector count (0:7) */
if (copy_to_user(arg, args, sizeof(args)))
rc = -EFAULT;
}
}


if (cmd_result) {
rc = -EIO;
goto error;
}

/* Need code to retrieve data from check condition? */

if ((argbuf)
&& copy_to_user(arg + sizeof(args), argbuf, argsize))
rc = -EFAULT;
error:
kfree(sensebuf);
kfree(argbuf);
return rc;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/ata/pata_qdi.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ static void qdi_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned
memcpy(&pad, buf + buflen - slop, slop);
outl(le32_to_cpu(pad), ap->ioaddr.data_addr);
} else {
pad = cpu_to_le16(inl(ap->ioaddr.data_addr));
pad = cpu_to_le32(inl(ap->ioaddr.data_addr));
memcpy(buf + buflen - slop, &pad, slop);
}
}
Expand Down
1 change: 1 addition & 0 deletions drivers/ata/sata_promise.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = {
#if 0
{ PCI_VDEVICE(PROMISE, 0x3570), board_20771 },
#endif
{ PCI_VDEVICE(PROMISE, 0x3577), board_20771 },

{ } /* terminate list */
};
Expand Down

0 comments on commit 6bf1f75

Please sign in to comment.