diff options
| author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-11 14:19:47 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-11 14:19:47 -0400 |
| commit | 6bf1f75bc6dabc357a29e3b3d6bd4ff00c3d5e6e (patch) | |
| tree | 556f9fa6e4b34082f3fbf54dfbd249b29967be28 /drivers | |
| parent | 60ca97584fcb98d2f1b14e4c2f12203dd5b3888e (diff) | |
| parent | 701328a7b58d50d8640c21ba5fdf3170b1ddac16 (diff) | |
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
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/ata/libata-core.c | 6 | ||||
| -rw-r--r-- | drivers/ata/libata-scsi.c | 46 | ||||
| -rw-r--r-- | drivers/ata/pata_qdi.c | 2 | ||||
| -rw-r--r-- | drivers/ata/sata_promise.c | 1 |
4 files changed, 46 insertions, 9 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 77138a39eb04..83728a9457ad 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -870,7 +870,11 @@ static unsigned int ata_id_xfermask(const u16 *id) | |||
| 870 | * the PIO timing number for the maximum. Turn it into | 870 | * the PIO timing number for the maximum. Turn it into |
| 871 | * a mask. | 871 | * a mask. |
| 872 | */ | 872 | */ |
| 873 | pio_mask = (2 << (id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ; | 873 | u8 mode = id[ATA_ID_OLD_PIO_MODES] & 0xFF; |
| 874 | if (mode < 5) /* Valid PIO range */ | ||
| 875 | pio_mask = (2 << mode) - 1; | ||
| 876 | else | ||
| 877 | pio_mask = 1; | ||
| 874 | 878 | ||
| 875 | /* But wait.. there's more. Design your standards by | 879 | /* But wait.. there's more. Design your standards by |
| 876 | * committee and you too can get a free iordy field to | 880 | * committee and you too can get a free iordy field to |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index b0d0cc41f3e8..7af2a4ba4990 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
| @@ -164,10 +164,10 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) | |||
| 164 | { | 164 | { |
| 165 | int rc = 0; | 165 | int rc = 0; |
| 166 | u8 scsi_cmd[MAX_COMMAND_SIZE]; | 166 | u8 scsi_cmd[MAX_COMMAND_SIZE]; |
| 167 | u8 args[4], *argbuf = NULL; | 167 | u8 args[4], *argbuf = NULL, *sensebuf = NULL; |
| 168 | int argsize = 0; | 168 | int argsize = 0; |
| 169 | struct scsi_sense_hdr sshdr; | ||
| 170 | enum dma_data_direction data_dir; | 169 | enum dma_data_direction data_dir; |
| 170 | int cmd_result; | ||
| 171 | 171 | ||
| 172 | if (arg == NULL) | 172 | if (arg == NULL) |
| 173 | return -EINVAL; | 173 | return -EINVAL; |
| @@ -175,6 +175,10 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) | |||
| 175 | if (copy_from_user(args, arg, sizeof(args))) | 175 | if (copy_from_user(args, arg, sizeof(args))) |
| 176 | return -EFAULT; | 176 | return -EFAULT; |
| 177 | 177 | ||
| 178 | sensebuf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO); | ||
| 179 | if (!sensebuf) | ||
| 180 | return -ENOMEM; | ||
| 181 | |||
| 178 | memset(scsi_cmd, 0, sizeof(scsi_cmd)); | 182 | memset(scsi_cmd, 0, sizeof(scsi_cmd)); |
| 179 | 183 | ||
| 180 | if (args[3]) { | 184 | if (args[3]) { |
| @@ -191,7 +195,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) | |||
| 191 | data_dir = DMA_FROM_DEVICE; | 195 | data_dir = DMA_FROM_DEVICE; |
| 192 | } else { | 196 | } else { |
| 193 | scsi_cmd[1] = (3 << 1); /* Non-data */ | 197 | scsi_cmd[1] = (3 << 1); /* Non-data */ |
| 194 | /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */ | 198 | scsi_cmd[2] = 0x20; /* cc but no off.line or data xfer */ |
| 195 | data_dir = DMA_NONE; | 199 | data_dir = DMA_NONE; |
| 196 | } | 200 | } |
| 197 | 201 | ||
| @@ -210,18 +214,46 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) | |||
| 210 | 214 | ||
| 211 | /* Good values for timeout and retries? Values below | 215 | /* Good values for timeout and retries? Values below |
| 212 | from scsi_ioctl_send_command() for default case... */ | 216 | from scsi_ioctl_send_command() for default case... */ |
| 213 | if (scsi_execute_req(scsidev, scsi_cmd, data_dir, argbuf, argsize, | 217 | cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize, |
| 214 | &sshdr, (10*HZ), 5)) { | 218 | sensebuf, (10*HZ), 5, 0); |
| 219 | |||
| 220 | if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */ | ||
| 221 | u8 *desc = sensebuf + 8; | ||
| 222 | cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */ | ||
| 223 | |||
| 224 | /* If we set cc then ATA pass-through will cause a | ||
| 225 | * check condition even if no error. Filter that. */ | ||
| 226 | if (cmd_result & SAM_STAT_CHECK_CONDITION) { | ||
| 227 | struct scsi_sense_hdr sshdr; | ||
| 228 | scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, | ||
| 229 | &sshdr); | ||
| 230 | if (sshdr.sense_key==0 && | ||
| 231 | sshdr.asc==0 && sshdr.ascq==0) | ||
| 232 | cmd_result &= ~SAM_STAT_CHECK_CONDITION; | ||
| 233 | } | ||
| 234 | |||
| 235 | /* Send userspace a few ATA registers (same as drivers/ide) */ | ||
| 236 | if (sensebuf[0] == 0x72 && /* format is "descriptor" */ | ||
| 237 | desc[0] == 0x09 ) { /* code is "ATA Descriptor" */ | ||
| 238 | args[0] = desc[13]; /* status */ | ||
| 239 | args[1] = desc[3]; /* error */ | ||
| 240 | args[2] = desc[5]; /* sector count (0:7) */ | ||
| 241 | if (copy_to_user(arg, args, sizeof(args))) | ||
| 242 | rc = -EFAULT; | ||
| 243 | } | ||
| 244 | } | ||
| 245 | |||
| 246 | |||
| 247 | if (cmd_result) { | ||
| 215 | rc = -EIO; | 248 | rc = -EIO; |
| 216 | goto error; | 249 | goto error; |
| 217 | } | 250 | } |
| 218 | 251 | ||
| 219 | /* Need code to retrieve data from check condition? */ | ||
| 220 | |||
| 221 | if ((argbuf) | 252 | if ((argbuf) |
| 222 | && copy_to_user(arg + sizeof(args), argbuf, argsize)) | 253 | && copy_to_user(arg + sizeof(args), argbuf, argsize)) |
| 223 | rc = -EFAULT; | 254 | rc = -EFAULT; |
| 224 | error: | 255 | error: |
| 256 | kfree(sensebuf); | ||
| 225 | kfree(argbuf); | 257 | kfree(argbuf); |
| 226 | return rc; | 258 | return rc; |
| 227 | } | 259 | } |
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c index 7977f471d5e9..2c3cc0ccc606 100644 --- a/drivers/ata/pata_qdi.c +++ b/drivers/ata/pata_qdi.c | |||
| @@ -141,7 +141,7 @@ static void qdi_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned | |||
| 141 | memcpy(&pad, buf + buflen - slop, slop); | 141 | memcpy(&pad, buf + buflen - slop, slop); |
| 142 | outl(le32_to_cpu(pad), ap->ioaddr.data_addr); | 142 | outl(le32_to_cpu(pad), ap->ioaddr.data_addr); |
| 143 | } else { | 143 | } else { |
| 144 | pad = cpu_to_le16(inl(ap->ioaddr.data_addr)); | 144 | pad = cpu_to_le32(inl(ap->ioaddr.data_addr)); |
| 145 | memcpy(buf + buflen - slop, &pad, slop); | 145 | memcpy(buf + buflen - slop, &pad, slop); |
| 146 | } | 146 | } |
| 147 | } | 147 | } |
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 8bcdfa64667c..72eda5160fad 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c | |||
| @@ -260,6 +260,7 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = { | |||
| 260 | #if 0 | 260 | #if 0 |
| 261 | { PCI_VDEVICE(PROMISE, 0x3570), board_20771 }, | 261 | { PCI_VDEVICE(PROMISE, 0x3570), board_20771 }, |
| 262 | #endif | 262 | #endif |
| 263 | { PCI_VDEVICE(PROMISE, 0x3577), board_20771 }, | ||
| 263 | 264 | ||
| 264 | { } /* terminate list */ | 265 | { } /* terminate list */ |
| 265 | }; | 266 | }; |
