[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1284701695-18367-1-git-send-email-nab@linux-iscsi.org>
Date: Thu, 16 Sep 2010 22:34:55 -0700
From: "Nicholas A. Bellinger" <nab@...ux-iscsi.org>
To: linux-scsi <linux-scsi@...r.kernel.org>,
linux-kernel <linux-kernel@...r.kernel.org>,
"Martin K. Petersen" <martin.petersen@...cle.com>,
James Bottomley <James.Bottomley@...e.de>,
Mike Christie <michaelc@...wisc.edu>,
FUJITA Tomonori <fujita.tomonori@....ntt.co.jp>
Cc: Hannes Reinecke <hare@...e.de>,
Konrad Rzeszutek Wilk <konrad@...nok.org>,
Douglas Gilbert <dgilbert@...erlog.com>,
Joe Eykholt <jeykholt@...co.com>,
Boaz Harrosh <bharrosh@...asas.com>,
Nicholas Bellinger <nab@...ux-iscsi.org>
Subject: [PATCH 2/3] tcm: Add VARIABLE_LENGTH_CMD support w/ XDWRITE_READ_32 emulation
From: Nicholas Bellinger <nab@...ux-iscsi.org>
This patch updates transport_generic_cmd_sequencer() to properly support
VARIABLE_LENGTH_CMD w/ service action XDWRITE_READ_32 emulation. This
patch follows the original XDWRITE_READ_10 patch, and uses the new 32-byte
CDB extraction callers from commit 39a347ca2d88. Note this patch uses the
same transport_xor_callback() assignment callback as XDWRITE_READ_10.
Also note that this patch enforces the following > TCM_MAX_COMMAND_SIZE check
for VARIABLE_LENGTH_CMD CDBs in transport_generic_cmd_sequencer():
<SNIP>
/*
* Check the additional CDB length (+ 8 bytes for header) does
* not exceed our TCM_MAX_COMMAND_SIZE.
*/
if ((cdb[7] + 8) > TCM_MAX_COMMAND_SIZE) {
printk(KERN_INFO "Only %u-byte extended CDBs currently"
" supported for VARIABLE_LENGTH_CMD, received:"
" %d for service action: 0x%04x\n",
TCM_MAX_COMMAND_SIZE, cdb[7], service_action);
return TGCS_INVALID_CDB_FIELD;
}
<SNIP>
Signed-off-by: Nicholas A. Bellinger <nab@...ux-iscsi.org>
---
drivers/target/target_core_transport.c | 50 +++++++++++++++++++++++++++----
1 files changed, 43 insertions(+), 7 deletions(-)
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index a3016f7..a20a4a9 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -5401,6 +5401,7 @@ static int transport_generic_cmd_sequencer(
struct se_subsystem_dev *su_dev = dev->se_sub_dev;
int ret, sector_ret = 0;
u32 sectors = 0, size = 0, pr_reg_type = 0;
+ u16 service_action;
u8 alua_ascq = 0;
/*
* Check for an existing UNIT ATTENTION condition
@@ -5572,6 +5573,48 @@ static int transport_generic_cmd_sequencer(
T_TASK(cmd)->t_tasks_fua = (cdb[1] & 0x8);
ret = TGCS_DATA_SG_IO_CDB;
break;
+ case VARIABLE_LENGTH_CMD:
+ SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
+ service_action = (cdb[8] << 8) | cdb[9];
+ /*
+ * Check the additional CDB length (+ 8 bytes for header) does
+ * not exceed our TCM_MAX_COMMAND_SIZE.
+ */
+ if ((cdb[7] + 8) > TCM_MAX_COMMAND_SIZE) {
+ printk(KERN_INFO "Only %u-byte extended CDBs currently"
+ " supported for VARIABLE_LENGTH_CMD, received:"
+ " %d for service action: 0x%04x\n",
+ TCM_MAX_COMMAND_SIZE, cdb[7], service_action);
+ return TGCS_INVALID_CDB_FIELD;
+ }
+ switch (service_action) {
+ case 0x0007: /* XDWRITE_READ_32 */
+ sectors = transport_get_sectors_32(cdb, cmd, §or_ret);
+ if (sector_ret)
+ return TGCS_UNSUPPORTED_CDB;
+ size = transport_get_size(sectors, cdb, cmd);
+ transport_dev_get_mem_SG(cmd->se_orig_obj_ptr, cmd);
+ transport_get_maps(cmd);
+ /*
+ * Use WRITE_32 and READ_32 opcodes for the emulated
+ * XDWRITE_READ_32 logic.
+ */
+ cmd->transport_split_cdb = &split_cdb_XX_32;
+ cmd->transport_get_long_lba = &transport_lba_64_ext;
+ /*
+ * Setup BIDI XOR callback to be run during
+ * transport_generic_complete_ok()
+ */
+ cmd->transport_complete_callback = &transport_xor_callback;
+ T_TASK(cmd)->t_tasks_fua = (cdb[10] & 0x8);
+ ret = TGCS_DATA_SG_IO_CDB;
+ break;
+ default:
+ printk(KERN_ERR "VARIABLE_LENGTH_CMD service action"
+ " 0x%04x not supported\n", service_action);
+ return TGCS_UNSUPPORTED_CDB;
+ }
+ break;
case 0xa3:
SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
if (TRANSPORT(dev)->get_device_type(dev) != TYPE_ROM) {
@@ -5747,13 +5790,6 @@ static int transport_generic_cmd_sequencer(
transport_get_maps(cmd);
ret = TGCS_CONTROL_NONSG_IO_CDB;
break;
- case VARIABLE_LENGTH_CMD:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
- size = (cdb[10] << 8) | cdb[11];
- transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
- transport_get_maps(cmd);
- ret = TGCS_CONTROL_NONSG_IO_CDB;
- break;
case RECEIVE_DIAGNOSTIC:
case SEND_DIAGNOSTIC:
SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
--
1.5.6.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists