diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2006-01-17 10:26:28 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-01-17 10:26:28 -0500 |
commit | 0825788ff27c7145e9d558cb2a26f3837d1f9be5 (patch) | |
tree | f6bdb892cec8ca0df69c08a3477c89f1542999e5 /drivers/scsi/libata-scsi.c | |
parent | 02f693c7118f6be9e677070eb630c1f3a654cdd3 (diff) | |
parent | 1bc4ccfff8675adc3d96f91245eb7e2dc0043ca9 (diff) |
Merge branch 'upstream'
Diffstat (limited to 'drivers/scsi/libata-scsi.c')
-rw-r--r-- | drivers/scsi/libata-scsi.c | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 094c9c88a095..0e65bfe92e6f 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -396,6 +396,22 @@ void ata_dump_status(unsigned id, struct ata_taskfile *tf) | |||
396 | } | 396 | } |
397 | } | 397 | } |
398 | 398 | ||
399 | int ata_scsi_device_resume(struct scsi_device *sdev) | ||
400 | { | ||
401 | struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0]; | ||
402 | struct ata_device *dev = &ap->device[sdev->id]; | ||
403 | |||
404 | return ata_device_resume(ap, dev); | ||
405 | } | ||
406 | |||
407 | int ata_scsi_device_suspend(struct scsi_device *sdev) | ||
408 | { | ||
409 | struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0]; | ||
410 | struct ata_device *dev = &ap->device[sdev->id]; | ||
411 | |||
412 | return ata_device_suspend(ap, dev); | ||
413 | } | ||
414 | |||
399 | /** | 415 | /** |
400 | * ata_to_sense_error - convert ATA error to SCSI error | 416 | * ata_to_sense_error - convert ATA error to SCSI error |
401 | * @id: ATA device number | 417 | * @id: ATA device number |
@@ -1078,11 +1094,13 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm | |||
1078 | scsicmd[0] == WRITE_16) | 1094 | scsicmd[0] == WRITE_16) |
1079 | tf->flags |= ATA_TFLAG_WRITE; | 1095 | tf->flags |= ATA_TFLAG_WRITE; |
1080 | 1096 | ||
1081 | /* Calculate the SCSI LBA and transfer length. */ | 1097 | /* Calculate the SCSI LBA, transfer length and FUA. */ |
1082 | switch (scsicmd[0]) { | 1098 | switch (scsicmd[0]) { |
1083 | case READ_10: | 1099 | case READ_10: |
1084 | case WRITE_10: | 1100 | case WRITE_10: |
1085 | scsi_10_lba_len(scsicmd, &block, &n_block); | 1101 | scsi_10_lba_len(scsicmd, &block, &n_block); |
1102 | if (unlikely(scsicmd[1] & (1 << 3))) | ||
1103 | tf->flags |= ATA_TFLAG_FUA; | ||
1086 | break; | 1104 | break; |
1087 | case READ_6: | 1105 | case READ_6: |
1088 | case WRITE_6: | 1106 | case WRITE_6: |
@@ -1097,6 +1115,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm | |||
1097 | case READ_16: | 1115 | case READ_16: |
1098 | case WRITE_16: | 1116 | case WRITE_16: |
1099 | scsi_16_lba_len(scsicmd, &block, &n_block); | 1117 | scsi_16_lba_len(scsicmd, &block, &n_block); |
1118 | if (unlikely(scsicmd[1] & (1 << 3))) | ||
1119 | tf->flags |= ATA_TFLAG_FUA; | ||
1100 | break; | 1120 | break; |
1101 | default: | 1121 | default: |
1102 | DPRINTK("no-byte command\n"); | 1122 | DPRINTK("no-byte command\n"); |
@@ -1136,7 +1156,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm | |||
1136 | /* request too large even for LBA48 */ | 1156 | /* request too large even for LBA48 */ |
1137 | goto out_of_range; | 1157 | goto out_of_range; |
1138 | 1158 | ||
1139 | ata_rwcmd_protocol(qc); | 1159 | if (unlikely(ata_rwcmd_protocol(qc) < 0)) |
1160 | goto invalid_fld; | ||
1140 | 1161 | ||
1141 | qc->nsect = n_block; | 1162 | qc->nsect = n_block; |
1142 | tf->nsect = n_block & 0xff; | 1163 | tf->nsect = n_block & 0xff; |
@@ -1154,7 +1175,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm | |||
1154 | if (!lba_28_ok(block, n_block)) | 1175 | if (!lba_28_ok(block, n_block)) |
1155 | goto out_of_range; | 1176 | goto out_of_range; |
1156 | 1177 | ||
1157 | ata_rwcmd_protocol(qc); | 1178 | if (unlikely(ata_rwcmd_protocol(qc) < 0)) |
1179 | goto invalid_fld; | ||
1158 | 1180 | ||
1159 | /* Convert LBA to CHS */ | 1181 | /* Convert LBA to CHS */ |
1160 | track = (u32)block / dev->sectors; | 1182 | track = (u32)block / dev->sectors; |
@@ -1689,6 +1711,7 @@ static unsigned int ata_msense_rw_recovery(u8 **ptr_io, const u8 *last) | |||
1689 | unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf, | 1711 | unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf, |
1690 | unsigned int buflen) | 1712 | unsigned int buflen) |
1691 | { | 1713 | { |
1714 | struct ata_device *dev = args->dev; | ||
1692 | u8 *scsicmd = args->cmd->cmnd, *p, *last; | 1715 | u8 *scsicmd = args->cmd->cmnd, *p, *last; |
1693 | const u8 sat_blk_desc[] = { | 1716 | const u8 sat_blk_desc[] = { |
1694 | 0, 0, 0, 0, /* number of blocks: sat unspecified */ | 1717 | 0, 0, 0, 0, /* number of blocks: sat unspecified */ |
@@ -1697,6 +1720,7 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf, | |||
1697 | }; | 1720 | }; |
1698 | u8 pg, spg; | 1721 | u8 pg, spg; |
1699 | unsigned int ebd, page_control, six_byte, output_len, alloc_len, minlen; | 1722 | unsigned int ebd, page_control, six_byte, output_len, alloc_len, minlen; |
1723 | u8 dpofua; | ||
1700 | 1724 | ||
1701 | VPRINTK("ENTER\n"); | 1725 | VPRINTK("ENTER\n"); |
1702 | 1726 | ||
@@ -1765,9 +1789,17 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf, | |||
1765 | 1789 | ||
1766 | if (minlen < 1) | 1790 | if (minlen < 1) |
1767 | return 0; | 1791 | return 0; |
1792 | |||
1793 | dpofua = 0; | ||
1794 | if (ata_id_has_fua(args->id) && dev->flags & ATA_DFLAG_LBA48 && | ||
1795 | (!(dev->flags & ATA_DFLAG_PIO) || dev->multi_count)) | ||
1796 | dpofua = 1 << 4; | ||
1797 | |||
1768 | if (six_byte) { | 1798 | if (six_byte) { |
1769 | output_len--; | 1799 | output_len--; |
1770 | rbuf[0] = output_len; | 1800 | rbuf[0] = output_len; |
1801 | if (minlen > 2) | ||
1802 | rbuf[2] |= dpofua; | ||
1771 | if (ebd) { | 1803 | if (ebd) { |
1772 | if (minlen > 3) | 1804 | if (minlen > 3) |
1773 | rbuf[3] = sizeof(sat_blk_desc); | 1805 | rbuf[3] = sizeof(sat_blk_desc); |
@@ -1780,6 +1812,8 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf, | |||
1780 | rbuf[0] = output_len >> 8; | 1812 | rbuf[0] = output_len >> 8; |
1781 | if (minlen > 1) | 1813 | if (minlen > 1) |
1782 | rbuf[1] = output_len; | 1814 | rbuf[1] = output_len; |
1815 | if (minlen > 3) | ||
1816 | rbuf[3] |= dpofua; | ||
1783 | if (ebd) { | 1817 | if (ebd) { |
1784 | if (minlen > 7) | 1818 | if (minlen > 7) |
1785 | rbuf[7] = sizeof(sat_blk_desc); | 1819 | rbuf[7] = sizeof(sat_blk_desc); |
@@ -2440,7 +2474,7 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
2440 | if (xlat_func) | 2474 | if (xlat_func) |
2441 | ata_scsi_translate(ap, dev, cmd, done, xlat_func); | 2475 | ata_scsi_translate(ap, dev, cmd, done, xlat_func); |
2442 | else | 2476 | else |
2443 | ata_scsi_simulate(dev->id, cmd, done); | 2477 | ata_scsi_simulate(ap, dev, cmd, done); |
2444 | } else | 2478 | } else |
2445 | ata_scsi_translate(ap, dev, cmd, done, atapi_xlat); | 2479 | ata_scsi_translate(ap, dev, cmd, done, atapi_xlat); |
2446 | 2480 | ||
@@ -2463,14 +2497,16 @@ out_unlock: | |||
2463 | * spin_lock_irqsave(host_set lock) | 2497 | * spin_lock_irqsave(host_set lock) |
2464 | */ | 2498 | */ |
2465 | 2499 | ||
2466 | void ata_scsi_simulate(u16 *id, | 2500 | void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev, |
2467 | struct scsi_cmnd *cmd, | 2501 | struct scsi_cmnd *cmd, |
2468 | void (*done)(struct scsi_cmnd *)) | 2502 | void (*done)(struct scsi_cmnd *)) |
2469 | { | 2503 | { |
2470 | struct ata_scsi_args args; | 2504 | struct ata_scsi_args args; |
2471 | const u8 *scsicmd = cmd->cmnd; | 2505 | const u8 *scsicmd = cmd->cmnd; |
2472 | 2506 | ||
2473 | args.id = id; | 2507 | args.ap = ap; |
2508 | args.dev = dev; | ||
2509 | args.id = dev->id; | ||
2474 | args.cmd = cmd; | 2510 | args.cmd = cmd; |
2475 | args.done = done; | 2511 | args.done = done; |
2476 | 2512 | ||