On 06/14/2016 08:35 AM, Nicholas A. Bellinger wrote: > On Fri, 2016-06-10 at 12:05 -0700, Bart Van Assche wrote: >> On 06/09/2016 02:26 PM, Bryant G. Ly wrote: >>> +/** >>> + * ibmvscsis_modify_std_inquiry() - Modify STD Inquiry >>> + * >>> + * This function modifies the inquiry data prior to sending to initiator >>> + * so that we can support current AIX. Internally we are going to >>> + * add new ODM entries to support the emulation from LIO. This function >>> + * is temporary until those changes are done. >>> + */ >>> +static void ibmvscsis_modify_std_inquiry(struct se_cmd *se_cmd) >>> +{ >>> + struct se_device *dev = se_cmd->se_dev; >>> + u32 cmd_len = se_cmd->data_length; >>> + u32 repl_len; >>> + unsigned char *buf = NULL; >>> + >>> + if (cmd_len <= 8) >>> + return; >>> + >>> + buf = transport_kmap_data_sg(se_cmd); >>> + if (buf) { >>> + repl_len = 8; >>> + if (cmd_len - 8 < repl_len) >>> + repl_len = cmd_len - 8; >>> + memcpy(&buf[8], "IBM ", repl_len); >>> + >>> + if (cmd_len > 16) { >>> + repl_len = 16; >>> + if (cmd_len - 16 < repl_len) >>> + repl_len = cmd_len - 16; >>> + if (dev->transport->get_device_type(dev) == TYPE_ROM) >>> + memcpy(&buf[16], "VOPTA ", repl_len); >>> + else >>> + memcpy(&buf[16], "3303 NVDISK", repl_len); >>> + } >>> + if (cmd_len > 32) { >>> + repl_len = 4; >>> + if (cmd_len - 32 < repl_len) >>> + repl_len = cmd_len - 32; >>> + memcpy(&buf[32], "0001", repl_len); >>> + } >>> + transport_kunmap_data_sg(se_cmd); >>> + } >>> +} >> >> Christoph Hellwig had asked you *not* to modify the INQUIRY response >> generated by the target core. Had you noticed that comment? > > Yeah, so I wanted to avoid having to add a new target_core_fabric_ops > API caller just for this special case, but there might not be another > choice.. All what's needed is something like the (untested) patch below. As one can see no new function pointers have been added to target_core_fabric_ops. All that has been added are a few new data members. With the patch below ibmvscsis_modify_std_inquiry() can be left out and the target core will pick up the "IBM", "VOPTA", "3303 NVDISK" and "0001" strings through the target_core_fabric_ops instance in the ibmvscsis template. I think this is a much cleaner approach than keeping the ibmvscsis_modify_std_inquiry() function ... Bart. [PATCH] target: Make INQUIRY vendor, product ID and product revision configurable --- drivers/target/target_core_configfs.c | 4 ++++ drivers/target/target_core_spc.c | 22 +++++++++++++++++----- include/target/target_core_fabric.h | 6 ++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 2001005..32a74f7 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -442,6 +442,10 @@ static int target_fabric_tf_ops_check(const struct target_core_fabric_ops *tfo) pr_err("Missing tfo->fabric_drop_tpg()\n"); return -EINVAL; } + if (tfo->prod_id_cnt && !tfo->prod_id) { + pr_err("Missing tfo->prod_id\n"); + return -EINVAL; + } return 0; } diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 2a91ed3..32c8435 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -66,6 +66,9 @@ spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf) struct se_lun *lun = cmd->se_lun; struct se_device *dev = cmd->se_dev; struct se_session *sess = cmd->se_sess; + struct se_portal_group *tpg = lun->lun_tpg; + const struct target_core_fabric_ops *tfo = tpg->se_tpg_tfo; + const char *vendor, *prod_id, *prod_rev; /* Set RMB (removable media) for tape devices */ if (dev->transport->get_device_type(dev) == TYPE_TAPE) @@ -108,12 +111,21 @@ spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf) buf[7] = 0x2; /* CmdQue=1 */ - memcpy(&buf[8], "LIO-ORG ", 8); + vendor = tfo->t10_vend_id ? : "LIO-ORG"; + memset(&buf[8], 0x20, 8); + memcpy(&buf[8], vendor, min_t(int, strlen(vendor), 8)); + prod_id = dev->t10_wwn.model; + if (tfo->prod_id) { + int dev_type = dev->transport->get_device_type(dev); + + if (dev_type < tfo->prod_id_cnt && tfo->prod_id[dev_type]) + prod_id = tfo->prod_id[dev_type]; + } memset(&buf[16], 0x20, 16); - memcpy(&buf[16], dev->t10_wwn.model, - min_t(size_t, strlen(dev->t10_wwn.model), 16)); - memcpy(&buf[32], dev->t10_wwn.revision, - min_t(size_t, strlen(dev->t10_wwn.revision), 4)); + memcpy(&buf[16], prod_id, min_t(size_t, strlen(prod_id), 16)); + prod_rev = tfo->prod_rev ? : dev->t10_wwn.revision; + memset(&buf[32], 0x20, 4); + memcpy(&buf[32], prod_rev, min_t(size_t, strlen(prod_rev), 4)); buf[4] = 31; /* Set additional length to 31 */ return 0; diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index de44462..5a63000 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -85,6 +85,12 @@ struct target_core_fabric_ops { void (*fabric_drop_np)(struct se_tpg_np *); int (*fabric_init_nodeacl)(struct se_node_acl *, const char *); + /* For spc_emulate_inquiry_std() */ + const char *t10_vend_id; + int prod_id_cnt; /* Number of elements in the prod_id array */ + const char **prod_id; + const char *prod_rev; + struct configfs_attribute **tfc_discovery_attrs; struct configfs_attribute **tfc_wwn_attrs; struct configfs_attribute **tfc_tpg_base_attrs; -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html