diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-03-29 19:58:22 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-03-29 19:58:22 -0500 |
commit | 79072f38909e3d9883317238887460c39ddcc4cb (patch) | |
tree | 28369f5a844535ff836565eefd62695b0e890fa3 /drivers/scsi/libata-scsi.c | |
parent | 200d5a7684cc49ef4be40e832daf3f217e70dfbb (diff) | |
parent | 55d8ca4f8094246da6e71889a4e04bfafaa78b10 (diff) |
Merge branch 'upstream'
Diffstat (limited to 'drivers/scsi/libata-scsi.c')
-rw-r--r-- | drivers/scsi/libata-scsi.c | 89 |
1 files changed, 45 insertions, 44 deletions
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index b53ef494a206..410c78795ca8 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <scsi/scsi_eh.h> | 41 | #include <scsi/scsi_eh.h> |
42 | #include <scsi/scsi_device.h> | 42 | #include <scsi/scsi_device.h> |
43 | #include <scsi/scsi_request.h> | 43 | #include <scsi/scsi_request.h> |
44 | #include <scsi/scsi_transport.h> | ||
44 | #include <linux/libata.h> | 45 | #include <linux/libata.h> |
45 | #include <linux/hdreg.h> | 46 | #include <linux/hdreg.h> |
46 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
@@ -52,6 +53,7 @@ | |||
52 | typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd); | 53 | typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd); |
53 | static struct ata_device * | 54 | static struct ata_device * |
54 | ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev); | 55 | ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev); |
56 | enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd); | ||
55 | 57 | ||
56 | #define RW_RECOVERY_MPAGE 0x1 | 58 | #define RW_RECOVERY_MPAGE 0x1 |
57 | #define RW_RECOVERY_MPAGE_LEN 12 | 59 | #define RW_RECOVERY_MPAGE_LEN 12 |
@@ -92,6 +94,14 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = { | |||
92 | 0, 30 /* extended self test time, see 05-359r1 */ | 94 | 0, 30 /* extended self test time, see 05-359r1 */ |
93 | }; | 95 | }; |
94 | 96 | ||
97 | /* | ||
98 | * libata transport template. libata doesn't do real transport stuff. | ||
99 | * It just needs the eh_timed_out hook. | ||
100 | */ | ||
101 | struct scsi_transport_template ata_scsi_transport_template = { | ||
102 | .eh_timed_out = ata_scsi_timed_out, | ||
103 | }; | ||
104 | |||
95 | 105 | ||
96 | static void ata_scsi_invalid_field(struct scsi_cmnd *cmd, | 106 | static void ata_scsi_invalid_field(struct scsi_cmnd *cmd, |
97 | void (*done)(struct scsi_cmnd *)) | 107 | void (*done)(struct scsi_cmnd *)) |
@@ -246,7 +256,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) | |||
246 | scsi_cmd[14] = args[0]; | 256 | scsi_cmd[14] = args[0]; |
247 | 257 | ||
248 | /* Good values for timeout and retries? Values below | 258 | /* Good values for timeout and retries? Values below |
249 | from scsi_ioctl_send_command() for default case... */ | 259 | from scsi_ioctl_send_command() for default case... */ |
250 | if (scsi_execute_req(scsidev, scsi_cmd, DMA_NONE, NULL, 0, &sshdr, | 260 | if (scsi_execute_req(scsidev, scsi_cmd, DMA_NONE, NULL, 0, &sshdr, |
251 | (10*HZ), 5)) | 261 | (10*HZ), 5)) |
252 | rc = -EIO; | 262 | rc = -EIO; |
@@ -257,20 +267,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) | |||
257 | 267 | ||
258 | int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg) | 268 | int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg) |
259 | { | 269 | { |
260 | struct ata_port *ap; | ||
261 | struct ata_device *dev; | ||
262 | int val = -EINVAL, rc = -EINVAL; | 270 | int val = -EINVAL, rc = -EINVAL; |
263 | 271 | ||
264 | ap = (struct ata_port *) &scsidev->host->hostdata[0]; | ||
265 | if (!ap) | ||
266 | goto out; | ||
267 | |||
268 | dev = ata_scsi_find_dev(ap, scsidev); | ||
269 | if (!dev) { | ||
270 | rc = -ENODEV; | ||
271 | goto out; | ||
272 | } | ||
273 | |||
274 | switch (cmd) { | 272 | switch (cmd) { |
275 | case ATA_IOC_GET_IO32: | 273 | case ATA_IOC_GET_IO32: |
276 | val = 0; | 274 | val = 0; |
@@ -299,7 +297,6 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg) | |||
299 | break; | 297 | break; |
300 | } | 298 | } |
301 | 299 | ||
302 | out: | ||
303 | return rc; | 300 | return rc; |
304 | } | 301 | } |
305 | 302 | ||
@@ -404,12 +401,12 @@ int ata_scsi_device_resume(struct scsi_device *sdev) | |||
404 | return ata_device_resume(ap, dev); | 401 | return ata_device_resume(ap, dev); |
405 | } | 402 | } |
406 | 403 | ||
407 | int ata_scsi_device_suspend(struct scsi_device *sdev) | 404 | int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state) |
408 | { | 405 | { |
409 | struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0]; | 406 | struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0]; |
410 | struct ata_device *dev = &ap->device[sdev->id]; | 407 | struct ata_device *dev = &ap->device[sdev->id]; |
411 | 408 | ||
412 | return ata_device_suspend(ap, dev); | 409 | return ata_device_suspend(ap, dev, state); |
413 | } | 410 | } |
414 | 411 | ||
415 | /** | 412 | /** |
@@ -428,7 +425,7 @@ int ata_scsi_device_suspend(struct scsi_device *sdev) | |||
428 | * LOCKING: | 425 | * LOCKING: |
429 | * spin_lock_irqsave(host_set lock) | 426 | * spin_lock_irqsave(host_set lock) |
430 | */ | 427 | */ |
431 | void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, | 428 | void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, |
432 | u8 *ascq) | 429 | u8 *ascq) |
433 | { | 430 | { |
434 | int i; | 431 | int i; |
@@ -485,7 +482,7 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, | |||
485 | /* Look for drv_err */ | 482 | /* Look for drv_err */ |
486 | for (i = 0; sense_table[i][0] != 0xFF; i++) { | 483 | for (i = 0; sense_table[i][0] != 0xFF; i++) { |
487 | /* Look for best matches first */ | 484 | /* Look for best matches first */ |
488 | if ((sense_table[i][0] & drv_err) == | 485 | if ((sense_table[i][0] & drv_err) == |
489 | sense_table[i][0]) { | 486 | sense_table[i][0]) { |
490 | *sk = sense_table[i][1]; | 487 | *sk = sense_table[i][1]; |
491 | *asc = sense_table[i][2]; | 488 | *asc = sense_table[i][2]; |
@@ -508,7 +505,7 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, | |||
508 | } | 505 | } |
509 | } | 506 | } |
510 | /* No error? Undecoded? */ | 507 | /* No error? Undecoded? */ |
511 | printk(KERN_WARNING "ata%u: no sense translation for status: 0x%02x\n", | 508 | printk(KERN_WARNING "ata%u: no sense translation for status: 0x%02x\n", |
512 | id, drv_stat); | 509 | id, drv_stat); |
513 | 510 | ||
514 | /* We need a sensible error return here, which is tricky, and one | 511 | /* We need a sensible error return here, which is tricky, and one |
@@ -1140,14 +1137,14 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc | |||
1140 | 1137 | ||
1141 | DPRINTK("block %u track %u cyl %u head %u sect %u\n", | 1138 | DPRINTK("block %u track %u cyl %u head %u sect %u\n", |
1142 | (u32)block, track, cyl, head, sect); | 1139 | (u32)block, track, cyl, head, sect); |
1143 | 1140 | ||
1144 | /* Check whether the converted CHS can fit. | 1141 | /* Check whether the converted CHS can fit. |
1145 | Cylinder: 0-65535 | 1142 | Cylinder: 0-65535 |
1146 | Head: 0-15 | 1143 | Head: 0-15 |
1147 | Sector: 1-255*/ | 1144 | Sector: 1-255*/ |
1148 | if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) | 1145 | if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) |
1149 | goto out_of_range; | 1146 | goto out_of_range; |
1150 | 1147 | ||
1151 | tf->command = ATA_CMD_VERIFY; | 1148 | tf->command = ATA_CMD_VERIFY; |
1152 | tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ | 1149 | tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ |
1153 | tf->lbal = sect; | 1150 | tf->lbal = sect; |
@@ -1279,7 +1276,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm | |||
1279 | tf->lbal = block & 0xff; | 1276 | tf->lbal = block & 0xff; |
1280 | 1277 | ||
1281 | tf->device |= ATA_LBA; | 1278 | tf->device |= ATA_LBA; |
1282 | } else { | 1279 | } else { |
1283 | /* CHS */ | 1280 | /* CHS */ |
1284 | u32 sect, head, cyl, track; | 1281 | u32 sect, head, cyl, track; |
1285 | 1282 | ||
@@ -1299,8 +1296,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm | |||
1299 | DPRINTK("block %u track %u cyl %u head %u sect %u\n", | 1296 | DPRINTK("block %u track %u cyl %u head %u sect %u\n", |
1300 | (u32)block, track, cyl, head, sect); | 1297 | (u32)block, track, cyl, head, sect); |
1301 | 1298 | ||
1302 | /* Check whether the converted CHS can fit. | 1299 | /* Check whether the converted CHS can fit. |
1303 | Cylinder: 0-65535 | 1300 | Cylinder: 0-65535 |
1304 | Head: 0-15 | 1301 | Head: 0-15 |
1305 | Sector: 1-255*/ | 1302 | Sector: 1-255*/ |
1306 | if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) | 1303 | if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) |
@@ -1687,7 +1684,7 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf, | |||
1687 | 1684 | ||
1688 | if (buflen > (ATA_SERNO_LEN + num + 3)) { | 1685 | if (buflen > (ATA_SERNO_LEN + num + 3)) { |
1689 | /* piv=0, assoc=lu, code_set=ACSII, designator=vendor */ | 1686 | /* piv=0, assoc=lu, code_set=ACSII, designator=vendor */ |
1690 | rbuf[num + 0] = 2; | 1687 | rbuf[num + 0] = 2; |
1691 | rbuf[num + 3] = ATA_SERNO_LEN; | 1688 | rbuf[num + 3] = ATA_SERNO_LEN; |
1692 | num += 4; | 1689 | num += 4; |
1693 | ata_id_string(args->id, (unsigned char *) rbuf + num, | 1690 | ata_id_string(args->id, (unsigned char *) rbuf + num, |
@@ -1697,8 +1694,8 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf, | |||
1697 | if (buflen > (sat_model_serial_desc_len + num + 3)) { | 1694 | if (buflen > (sat_model_serial_desc_len + num + 3)) { |
1698 | /* SAT defined lu model and serial numbers descriptor */ | 1695 | /* SAT defined lu model and serial numbers descriptor */ |
1699 | /* piv=0, assoc=lu, code_set=ACSII, designator=t10 vendor id */ | 1696 | /* piv=0, assoc=lu, code_set=ACSII, designator=t10 vendor id */ |
1700 | rbuf[num + 0] = 2; | 1697 | rbuf[num + 0] = 2; |
1701 | rbuf[num + 1] = 1; | 1698 | rbuf[num + 1] = 1; |
1702 | rbuf[num + 3] = sat_model_serial_desc_len; | 1699 | rbuf[num + 3] = sat_model_serial_desc_len; |
1703 | num += 4; | 1700 | num += 4; |
1704 | memcpy(rbuf + num, "ATA ", 8); | 1701 | memcpy(rbuf + num, "ATA ", 8); |
@@ -2587,6 +2584,21 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap, | |||
2587 | #endif | 2584 | #endif |
2588 | } | 2585 | } |
2589 | 2586 | ||
2587 | static inline void __ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), | ||
2588 | struct ata_port *ap, struct ata_device *dev) | ||
2589 | { | ||
2590 | if (dev->class == ATA_DEV_ATA) { | ||
2591 | ata_xlat_func_t xlat_func = ata_get_xlat_func(dev, | ||
2592 | cmd->cmnd[0]); | ||
2593 | |||
2594 | if (xlat_func) | ||
2595 | ata_scsi_translate(ap, dev, cmd, done, xlat_func); | ||
2596 | else | ||
2597 | ata_scsi_simulate(ap, dev, cmd, done); | ||
2598 | } else | ||
2599 | ata_scsi_translate(ap, dev, cmd, done, atapi_xlat); | ||
2600 | } | ||
2601 | |||
2590 | /** | 2602 | /** |
2591 | * ata_scsi_queuecmd - Issue SCSI cdb to libata-managed device | 2603 | * ata_scsi_queuecmd - Issue SCSI cdb to libata-managed device |
2592 | * @cmd: SCSI command to be sent | 2604 | * @cmd: SCSI command to be sent |
@@ -2621,24 +2633,13 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
2621 | ata_scsi_dump_cdb(ap, cmd); | 2633 | ata_scsi_dump_cdb(ap, cmd); |
2622 | 2634 | ||
2623 | dev = ata_scsi_find_dev(ap, scsidev); | 2635 | dev = ata_scsi_find_dev(ap, scsidev); |
2624 | if (unlikely(!dev)) { | 2636 | if (likely(dev)) |
2637 | __ata_scsi_queuecmd(cmd, done, ap, dev); | ||
2638 | else { | ||
2625 | cmd->result = (DID_BAD_TARGET << 16); | 2639 | cmd->result = (DID_BAD_TARGET << 16); |
2626 | done(cmd); | 2640 | done(cmd); |
2627 | goto out_unlock; | ||
2628 | } | 2641 | } |
2629 | 2642 | ||
2630 | if (dev->class == ATA_DEV_ATA) { | ||
2631 | ata_xlat_func_t xlat_func = ata_get_xlat_func(dev, | ||
2632 | cmd->cmnd[0]); | ||
2633 | |||
2634 | if (xlat_func) | ||
2635 | ata_scsi_translate(ap, dev, cmd, done, xlat_func); | ||
2636 | else | ||
2637 | ata_scsi_simulate(ap, dev, cmd, done); | ||
2638 | } else | ||
2639 | ata_scsi_translate(ap, dev, cmd, done, atapi_xlat); | ||
2640 | |||
2641 | out_unlock: | ||
2642 | spin_unlock(&ap->host_set->lock); | 2643 | spin_unlock(&ap->host_set->lock); |
2643 | spin_lock(shost->host_lock); | 2644 | spin_lock(shost->host_lock); |
2644 | return 0; | 2645 | return 0; |