Commit 6bf1f75b authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/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
parents 60ca9758 701328a7
...@@ -870,7 +870,11 @@ static unsigned int ata_id_xfermask(const u16 *id) ...@@ -870,7 +870,11 @@ static unsigned int ata_id_xfermask(const u16 *id)
* the PIO timing number for the maximum. Turn it into * the PIO timing number for the maximum. Turn it into
* a mask. * 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 /* But wait.. there's more. Design your standards by
* committee and you too can get a free iordy field to * committee and you too can get a free iordy field to
......
...@@ -164,10 +164,10 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) ...@@ -164,10 +164,10 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
{ {
int rc = 0; int rc = 0;
u8 scsi_cmd[MAX_COMMAND_SIZE]; u8 scsi_cmd[MAX_COMMAND_SIZE];
u8 args[4], *argbuf = NULL; u8 args[4], *argbuf = NULL, *sensebuf = NULL;
int argsize = 0; int argsize = 0;
struct scsi_sense_hdr sshdr;
enum dma_data_direction data_dir; enum dma_data_direction data_dir;
int cmd_result;
if (arg == NULL) if (arg == NULL)
return -EINVAL; return -EINVAL;
...@@ -175,6 +175,10 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) ...@@ -175,6 +175,10 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
if (copy_from_user(args, arg, sizeof(args))) if (copy_from_user(args, arg, sizeof(args)))
return -EFAULT; return -EFAULT;
sensebuf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO);
if (!sensebuf)
return -ENOMEM;
memset(scsi_cmd, 0, sizeof(scsi_cmd)); memset(scsi_cmd, 0, sizeof(scsi_cmd));
if (args[3]) { if (args[3]) {
...@@ -191,7 +195,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) ...@@ -191,7 +195,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
data_dir = DMA_FROM_DEVICE; data_dir = DMA_FROM_DEVICE;
} else { } else {
scsi_cmd[1] = (3 << 1); /* Non-data */ 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; data_dir = DMA_NONE;
} }
...@@ -210,18 +214,46 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) ...@@ -210,18 +214,46 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
/* Good values for timeout and retries? Values below /* Good values for timeout and retries? Values below
from scsi_ioctl_send_command() for default case... */ from scsi_ioctl_send_command() for default case... */
if (scsi_execute_req(scsidev, scsi_cmd, data_dir, argbuf, argsize, cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize,
&sshdr, (10*HZ), 5)) { 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; rc = -EIO;
goto error; goto error;
} }
/* Need code to retrieve data from check condition? */
if ((argbuf) if ((argbuf)
&& copy_to_user(arg + sizeof(args), argbuf, argsize)) && copy_to_user(arg + sizeof(args), argbuf, argsize))
rc = -EFAULT; rc = -EFAULT;
error: error:
kfree(sensebuf);
kfree(argbuf); kfree(argbuf);
return rc; return rc;
} }
......
...@@ -141,7 +141,7 @@ static void qdi_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned ...@@ -141,7 +141,7 @@ static void qdi_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned
memcpy(&pad, buf + buflen - slop, slop); memcpy(&pad, buf + buflen - slop, slop);
outl(le32_to_cpu(pad), ap->ioaddr.data_addr); outl(le32_to_cpu(pad), ap->ioaddr.data_addr);
} else { } 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); memcpy(buf + buflen - slop, &pad, slop);
} }
} }
......
...@@ -260,6 +260,7 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = { ...@@ -260,6 +260,7 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = {
#if 0 #if 0
{ PCI_VDEVICE(PROMISE, 0x3570), board_20771 }, { PCI_VDEVICE(PROMISE, 0x3570), board_20771 },
#endif #endif
{ PCI_VDEVICE(PROMISE, 0x3577), board_20771 },
{ } /* terminate list */ { } /* terminate list */
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment