aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libata-scsi.c')
-rw-r--r--drivers/scsi/libata-scsi.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index c1ebede14a48..cfbceb504718 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -1096,11 +1096,13 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
1096 scsicmd[0] == WRITE_16) 1096 scsicmd[0] == WRITE_16)
1097 tf->flags |= ATA_TFLAG_WRITE; 1097 tf->flags |= ATA_TFLAG_WRITE;
1098 1098
1099 /* Calculate the SCSI LBA and transfer length. */ 1099 /* Calculate the SCSI LBA, transfer length and FUA. */
1100 switch (scsicmd[0]) { 1100 switch (scsicmd[0]) {
1101 case READ_10: 1101 case READ_10:
1102 case WRITE_10: 1102 case WRITE_10:
1103 scsi_10_lba_len(scsicmd, &block, &n_block); 1103 scsi_10_lba_len(scsicmd, &block, &n_block);
1104 if (unlikely(scsicmd[1] & (1 << 3)))
1105 tf->flags |= ATA_TFLAG_FUA;
1104 break; 1106 break;
1105 case READ_6: 1107 case READ_6:
1106 case WRITE_6: 1108 case WRITE_6:
@@ -1115,6 +1117,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
1115 case READ_16: 1117 case READ_16:
1116 case WRITE_16: 1118 case WRITE_16:
1117 scsi_16_lba_len(scsicmd, &block, &n_block); 1119 scsi_16_lba_len(scsicmd, &block, &n_block);
1120 if (unlikely(scsicmd[1] & (1 << 3)))
1121 tf->flags |= ATA_TFLAG_FUA;
1118 break; 1122 break;
1119 default: 1123 default:
1120 DPRINTK("no-byte command\n"); 1124 DPRINTK("no-byte command\n");
@@ -1158,7 +1162,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
1158 tf->device |= (block >> 24) & 0xf; 1162 tf->device |= (block >> 24) & 0xf;
1159 } 1163 }
1160 1164
1161 ata_rwcmd_protocol(qc); 1165 if (unlikely(ata_rwcmd_protocol(qc) < 0))
1166 goto invalid_fld;
1162 1167
1163 qc->nsect = n_block; 1168 qc->nsect = n_block;
1164 tf->nsect = n_block & 0xff; 1169 tf->nsect = n_block & 0xff;
@@ -1176,7 +1181,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
1176 if ((block >> 28) || (n_block > 256)) 1181 if ((block >> 28) || (n_block > 256))
1177 goto out_of_range; 1182 goto out_of_range;
1178 1183
1179 ata_rwcmd_protocol(qc); 1184 if (unlikely(ata_rwcmd_protocol(qc) < 0))
1185 goto invalid_fld;
1180 1186
1181 /* Convert LBA to CHS */ 1187 /* Convert LBA to CHS */
1182 track = (u32)block / dev->sectors; 1188 track = (u32)block / dev->sectors;
@@ -1711,6 +1717,7 @@ static unsigned int ata_msense_rw_recovery(u8 **ptr_io, const u8 *last)
1711unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf, 1717unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
1712 unsigned int buflen) 1718 unsigned int buflen)
1713{ 1719{
1720 struct ata_device *dev = args->dev;
1714 u8 *scsicmd = args->cmd->cmnd, *p, *last; 1721 u8 *scsicmd = args->cmd->cmnd, *p, *last;
1715 const u8 sat_blk_desc[] = { 1722 const u8 sat_blk_desc[] = {
1716 0, 0, 0, 0, /* number of blocks: sat unspecified */ 1723 0, 0, 0, 0, /* number of blocks: sat unspecified */
@@ -1719,6 +1726,7 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
1719 }; 1726 };
1720 u8 pg, spg; 1727 u8 pg, spg;
1721 unsigned int ebd, page_control, six_byte, output_len, alloc_len, minlen; 1728 unsigned int ebd, page_control, six_byte, output_len, alloc_len, minlen;
1729 u8 dpofua;
1722 1730
1723 VPRINTK("ENTER\n"); 1731 VPRINTK("ENTER\n");
1724 1732
@@ -1787,9 +1795,17 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
1787 1795
1788 if (minlen < 1) 1796 if (minlen < 1)
1789 return 0; 1797 return 0;
1798
1799 dpofua = 0;
1800 if (ata_id_has_fua(args->id) && dev->flags & ATA_DFLAG_LBA48 &&
1801 (!(dev->flags & ATA_DFLAG_PIO) || dev->multi_count))
1802 dpofua = 1 << 4;
1803
1790 if (six_byte) { 1804 if (six_byte) {
1791 output_len--; 1805 output_len--;
1792 rbuf[0] = output_len; 1806 rbuf[0] = output_len;
1807 if (minlen > 2)
1808 rbuf[2] |= dpofua;
1793 if (ebd) { 1809 if (ebd) {
1794 if (minlen > 3) 1810 if (minlen > 3)
1795 rbuf[3] = sizeof(sat_blk_desc); 1811 rbuf[3] = sizeof(sat_blk_desc);
@@ -1802,6 +1818,8 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
1802 rbuf[0] = output_len >> 8; 1818 rbuf[0] = output_len >> 8;
1803 if (minlen > 1) 1819 if (minlen > 1)
1804 rbuf[1] = output_len; 1820 rbuf[1] = output_len;
1821 if (minlen > 3)
1822 rbuf[3] |= dpofua;
1805 if (ebd) { 1823 if (ebd) {
1806 if (minlen > 7) 1824 if (minlen > 7)
1807 rbuf[7] = sizeof(sat_blk_desc); 1825 rbuf[7] = sizeof(sat_blk_desc);
@@ -2462,7 +2480,7 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
2462 if (xlat_func) 2480 if (xlat_func)
2463 ata_scsi_translate(ap, dev, cmd, done, xlat_func); 2481 ata_scsi_translate(ap, dev, cmd, done, xlat_func);
2464 else 2482 else
2465 ata_scsi_simulate(dev->id, cmd, done); 2483 ata_scsi_simulate(ap, dev, cmd, done);
2466 } else 2484 } else
2467 ata_scsi_translate(ap, dev, cmd, done, atapi_xlat); 2485 ata_scsi_translate(ap, dev, cmd, done, atapi_xlat);
2468 2486
@@ -2485,14 +2503,16 @@ out_unlock:
2485 * spin_lock_irqsave(host_set lock) 2503 * spin_lock_irqsave(host_set lock)
2486 */ 2504 */
2487 2505
2488void ata_scsi_simulate(u16 *id, 2506void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
2489 struct scsi_cmnd *cmd, 2507 struct scsi_cmnd *cmd,
2490 void (*done)(struct scsi_cmnd *)) 2508 void (*done)(struct scsi_cmnd *))
2491{ 2509{
2492 struct ata_scsi_args args; 2510 struct ata_scsi_args args;
2493 const u8 *scsicmd = cmd->cmnd; 2511 const u8 *scsicmd = cmd->cmnd;
2494 2512
2495 args.id = id; 2513 args.ap = ap;
2514 args.dev = dev;
2515 args.id = dev->id;
2496 args.cmd = cmd; 2516 args.cmd = cmd;
2497 args.done = done; 2517 args.done = done;
2498 2518