diff options
author | mengcong <mc@linux.vnet.ibm.com> | 2012-05-17 07:14:46 +0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-05-17 11:45:58 +0400 |
commit | 8da10935bc8358f03c9d90ed2e4a3bbaa19940ab (patch) | |
tree | 700e56db8e6515a0616460020686ed56f5f4bd48 /drivers/target/target_core_transport.c | |
parent | 5b9a4d7280e160982a8ea37bc03619f53b5c98b7 (diff) | |
download | linux-8da10935bc8358f03c9d90ed2e4a3bbaa19940ab.tar.xz |
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/target_core_transport.c')
-rw-r--r-- | drivers/target/target_core_transport.c | 32 |
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", |