summaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authormengcong <mc@linux.vnet.ibm.com>2012-05-17 11:14:46 +0800
committerNicholas Bellinger <nab@linux-iscsi.org>2012-05-17 00:45:58 -0700
commit8da10935bc8358f03c9d90ed2e4a3bbaa19940ab (patch)
tree700e56db8e6515a0616460020686ed56f5f4bd48 /drivers/target
parent5b9a4d7280e160982a8ea37bc03619f53b5c98b7 (diff)
downloadlinux-8da10935bc8358f03c9d90ed2e4a3bbaa19940ab.tar.gz
linux-8da10935bc8358f03c9d90ed2e4a3bbaa19940ab.tar.xz
linux-8da10935bc8358f03c9d90ed2e4a3bbaa19940ab.zip
target: Handle ATA_16 passthrough for pSCSI backend devices
The cdrecord uses ATA_PASS_THROUGH_16 command while burning CDs with a SATA CD-ROM. This patch adds support to it so that PSCSI CD-ROM passthrough works with the cdrecord. (nab: Add !passthrough check to prevent non pSCSI backends from ATA_16) Signed-off-by: Cong Meng <mc@linux.vnet.ibm.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/target_core_transport.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index f95a74da4d40..b05fdc0c05d3 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -2927,6 +2927,38 @@ static int transport_generic_cmd_sequencer(
size = (cdb[7] << 8) | cdb[8];
cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
break;
+ case ATA_16:
+ /* Only support ATA passthrough to pSCSI backends.. */
+ if (!passthrough)
+ goto out_unsupported_cdb;
+
+ /* T_LENGTH */
+ switch (cdb[2] & 0x3) {
+ case 0x0:
+ sectors = 0;
+ break;
+ case 0x1:
+ sectors = (((cdb[1] & 0x1) ? cdb[3] : 0) << 8) | cdb[4];
+ break;
+ case 0x2:
+ sectors = (((cdb[1] & 0x1) ? cdb[5] : 0) << 8) | cdb[6];
+ break;
+ case 0x3:
+ pr_err("T_LENGTH=0x3 not supported for ATA_16\n");
+ goto out_invalid_cdb_field;
+ }
+
+ /* BYTE_BLOCK */
+ if (cdb[2] & 0x4) {
+ /* BLOCK T_TYPE: 512 or sector */
+ size = sectors * ((cdb[2] & 0x10) ?
+ dev->se_sub_dev->se_dev_attrib.block_size : 512);
+ } else {
+ /* BYTE */
+ size = sectors;
+ }
+ cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
+ break;
default:
pr_warn("TARGET_CORE[%s]: Unsupported SCSI Opcode"
" 0x%02x, sending CHECK_CONDITION.\n",