aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-12-16 20:46:33 -0500
committerJeff Garzik <jeff@garzik.org>2006-12-20 14:26:26 -0500
commit2e5704f63ed56b040a3189f6b7eb17f6f849ea22 (patch)
tree4b3df2d375da3fefa5a8d22f6f41a9e5f7ce5798 /drivers/ata
parentad706991f4f0d1476aecbdae2df5e36552b340b2 (diff)
[PATCH] libata: take scmd->cmd_len into account when translating SCSI commands
libata depended on SCSI command to have the correct length when tranlating it into an ATA command. This generally worked for commands issued by SCSI HLD but user could issue arbitrary broken command using sg interface. Also, when building ATAPI command, full command size was always copied. Because some ATAPI devices needs bytes after CDB cleared, if upper layer doesn't clear bytes after CDB, such devices will malfunction. This necessiated recent clear-garbage-after-CDB fix in sg interfaces. However, scsi_execute() isn't fixed yet and HL-DT-ST DVD-RAM GSA-H30N malfunctions on initialization commands issued from SCSI. This patch makes xlat functions always consider SCSI cmd_len. Each translation function checks for proper cmd_len and ATAPI translaation clears bytes after CDB. Signed-off-by: Tejun Heo <htejun@gmail.com> Cc: Jens Axboe <jens.axboe@oracle.com> Cc: Douglas Gilbert <dougg@torque.net> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-scsi.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 307910bd62c3..836947da5b14 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -953,6 +953,9 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
953 struct ata_taskfile *tf = &qc->tf; 953 struct ata_taskfile *tf = &qc->tf;
954 const u8 *cdb = scmd->cmnd; 954 const u8 *cdb = scmd->cmnd;
955 955
956 if (scmd->cmd_len < 5)
957 goto invalid_fld;
958
956 tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; 959 tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
957 tf->protocol = ATA_PROT_NODATA; 960 tf->protocol = ATA_PROT_NODATA;
958 if (cdb[1] & 0x1) { 961 if (cdb[1] & 0x1) {
@@ -1144,11 +1147,15 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc)
1144 tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; 1147 tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
1145 tf->protocol = ATA_PROT_NODATA; 1148 tf->protocol = ATA_PROT_NODATA;
1146 1149
1147 if (cdb[0] == VERIFY) 1150 if (cdb[0] == VERIFY) {
1151 if (scmd->cmd_len < 10)
1152 goto invalid_fld;
1148 scsi_10_lba_len(cdb, &block, &n_block); 1153 scsi_10_lba_len(cdb, &block, &n_block);
1149 else if (cdb[0] == VERIFY_16) 1154 } else if (cdb[0] == VERIFY_16) {
1155 if (scmd->cmd_len < 16)
1156 goto invalid_fld;
1150 scsi_16_lba_len(cdb, &block, &n_block); 1157 scsi_16_lba_len(cdb, &block, &n_block);
1151 else 1158 } else
1152 goto invalid_fld; 1159 goto invalid_fld;
1153 1160
1154 if (!n_block) 1161 if (!n_block)
@@ -1271,12 +1278,16 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
1271 switch (cdb[0]) { 1278 switch (cdb[0]) {
1272 case READ_10: 1279 case READ_10:
1273 case WRITE_10: 1280 case WRITE_10:
1281 if (unlikely(scmd->cmd_len < 10))
1282 goto invalid_fld;
1274 scsi_10_lba_len(cdb, &block, &n_block); 1283 scsi_10_lba_len(cdb, &block, &n_block);
1275 if (unlikely(cdb[1] & (1 << 3))) 1284 if (unlikely(cdb[1] & (1 << 3)))
1276 tf_flags |= ATA_TFLAG_FUA; 1285 tf_flags |= ATA_TFLAG_FUA;
1277 break; 1286 break;
1278 case READ_6: 1287 case READ_6:
1279 case WRITE_6: 1288 case WRITE_6:
1289 if (unlikely(scmd->cmd_len < 6))
1290 goto invalid_fld;
1280 scsi_6_lba_len(cdb, &block, &n_block); 1291 scsi_6_lba_len(cdb, &block, &n_block);
1281 1292
1282 /* for 6-byte r/w commands, transfer length 0 1293 /* for 6-byte r/w commands, transfer length 0
@@ -1287,6 +1298,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
1287 break; 1298 break;
1288 case READ_16: 1299 case READ_16:
1289 case WRITE_16: 1300 case WRITE_16:
1301 if (unlikely(scmd->cmd_len < 16))
1302 goto invalid_fld;
1290 scsi_16_lba_len(cdb, &block, &n_block); 1303 scsi_16_lba_len(cdb, &block, &n_block);
1291 if (unlikely(cdb[1] & (1 << 3))) 1304 if (unlikely(cdb[1] & (1 << 3)))
1292 tf_flags |= ATA_TFLAG_FUA; 1305 tf_flags |= ATA_TFLAG_FUA;
@@ -2355,7 +2368,8 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
2355 if (ata_check_atapi_dma(qc)) 2368 if (ata_check_atapi_dma(qc))
2356 using_pio = 1; 2369 using_pio = 1;
2357 2370
2358 memcpy(&qc->cdb, scmd->cmnd, dev->cdb_len); 2371 memset(qc->cdb, 0, dev->cdb_len);
2372 memcpy(qc->cdb, scmd->cmnd, scmd->cmd_len);
2359 2373
2360 qc->complete_fn = atapi_qc_complete; 2374 qc->complete_fn = atapi_qc_complete;
2361 2375
@@ -2696,6 +2710,13 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
2696{ 2710{
2697 int rc = 0; 2711 int rc = 0;
2698 2712
2713 if (unlikely(!scmd->cmd_len)) {
2714 ata_dev_printk(dev, KERN_WARNING, "WARNING: zero len CDB\n");
2715 scmd->result = DID_ERROR << 16;
2716 done(scmd);
2717 return 0;
2718 }
2719
2699 if (dev->class == ATA_DEV_ATA) { 2720 if (dev->class == ATA_DEV_ATA) {
2700 ata_xlat_func_t xlat_func = ata_get_xlat_func(dev, 2721 ata_xlat_func_t xlat_func = ata_get_xlat_func(dev,
2701 scmd->cmnd[0]); 2722 scmd->cmnd[0]);