diff options
author | mengcong <mc@linux.vnet.ibm.com> | 2012-05-16 23:14:46 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-05-17 03:45:58 -0400 |
commit | 8da10935bc8358f03c9d90ed2e4a3bbaa19940ab (patch) | |
tree | 700e56db8e6515a0616460020686ed56f5f4bd48 /drivers/target | |
parent | 5b9a4d7280e160982a8ea37bc03619f53b5c98b7 (diff) |
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.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( | |||
2927 | size = (cdb[7] << 8) | cdb[8]; | 2927 | size = (cdb[7] << 8) | cdb[8]; |
2928 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; | 2928 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; |
2929 | break; | 2929 | break; |
2930 | case ATA_16: | ||
2931 | /* Only support ATA passthrough to pSCSI backends.. */ | ||
2932 | if (!passthrough) | ||
2933 | goto out_unsupported_cdb; | ||
2934 | |||
2935 | /* T_LENGTH */ | ||
2936 | switch (cdb[2] & 0x3) { | ||
2937 | case 0x0: | ||
2938 | sectors = 0; | ||
2939 | break; | ||
2940 | case 0x1: | ||
2941 | sectors = (((cdb[1] & 0x1) ? cdb[3] : 0) << 8) | cdb[4]; | ||
2942 | break; | ||
2943 | case 0x2: | ||
2944 | sectors = (((cdb[1] & 0x1) ? cdb[5] : 0) << 8) | cdb[6]; | ||
2945 | break; | ||
2946 | case 0x3: | ||
2947 | pr_err("T_LENGTH=0x3 not supported for ATA_16\n"); | ||
2948 | goto out_invalid_cdb_field; | ||
2949 | } | ||
2950 | |||
2951 | /* BYTE_BLOCK */ | ||
2952 | if (cdb[2] & 0x4) { | ||
2953 | /* BLOCK T_TYPE: 512 or sector */ | ||
2954 | size = sectors * ((cdb[2] & 0x10) ? | ||
2955 | dev->se_sub_dev->se_dev_attrib.block_size : 512); | ||
2956 | } else { | ||
2957 | /* BYTE */ | ||
2958 | size = sectors; | ||
2959 | } | ||
2960 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; | ||
2961 | break; | ||
2930 | default: | 2962 | default: |
2931 | pr_warn("TARGET_CORE[%s]: Unsupported SCSI Opcode" | 2963 | pr_warn("TARGET_CORE[%s]: Unsupported SCSI Opcode" |
2932 | " 0x%02x, sending CHECK_CONDITION.\n", | 2964 | " 0x%02x, sending CHECK_CONDITION.\n", |