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
This commit is contained in:
commit
6bf1f75bc6
@ -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
|
||||
|
@ -164,10 +164,10 @@ 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;
|
||||
@ -175,6 +175,10 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
|
||||
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]) {
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user