[PATCH 2/5] tcm: Unify INQUIRY subsystem plugin handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>

This patch adds the following two struct se_subsystem_api function pointer
ops for INQUIRY emulation reponse payload Product and Product Rev:

       /*
        * Used to obtain INQUIRY Product field field
        */
       char *(*get_inquiry_prod)(struct se_device *);
       /*
        * Used to obtain INQUIRY Production revision field
        */
       char *(*get_inquiry_rev)(struct se_device *);

and updates virtual IBLOCK, FILEIO and RAMDISK_[DR,MCP] to return their
respective informational INQUIRY emulation values.

Signed-off-by: Nicholas A. Bellinger <nab@xxxxxxxxxxxxxxx>
Reported-by: Christoph Hellwig <hch@xxxxxx>
---
 drivers/target/target_core_file.c      |   34 ++++++----------
 drivers/target/target_core_iblock.c    |   31 ++++++---------
 drivers/target/target_core_rd.c        |   41 ++++++++-----------
 drivers/target/target_core_transport.c |   67 ++++++++++++--------------------
 include/target/target_core_transport.h |   12 ++++-
 5 files changed, 76 insertions(+), 109 deletions(-)

diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index a5ad51c..97e068f 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -358,27 +358,6 @@ static void *fd_allocate_request(
 	return (void *)fd_req;
 }
 
-/*	fd_emulate_inquiry():
- *
- *
- */
-static int fd_emulate_inquiry(struct se_task *task)
-{
-	unsigned char prod[64], se_location[128];
-	struct se_cmd *cmd = TASK_CMD(task);
-	struct fd_dev *fdev = task->se_dev->dev_ptr;
-	struct se_hba *hba = task->se_dev->se_hba;
-
-	memset(prod, 0, 64);
-	memset(se_location, 0, 128);
-
-	sprintf(prod, "FILEIO");
-	sprintf(se_location, "%u_%u", hba->hba_id, fdev->fd_dev_id);
-
-	return transport_generic_emulate_inquiry(cmd, TYPE_DISK, prod,
-		FD_VERSION, se_location);
-}
-
 /*	fd_emulate_read_cap():
  *
  *
@@ -1130,6 +1109,16 @@ static u32 fd_get_device_type(struct se_device *dev)
 	return TYPE_DISK;
 }
 
+static char *fd_get_inquiry_prod(struct se_device *dev)
+{
+	return "FILEIO";
+}
+
+static char *fd_get_inquiry_rev(struct se_device *dev)
+{
+	return FD_VERSION;
+}
+
 /*	fd_get_dma_length(): (Part of se_subsystem_api_t template)
  *
  *
@@ -1203,6 +1192,8 @@ static struct se_subsystem_api fileio_template = {
 	.get_blocksize		= fd_get_blocksize,
 	.get_device_rev		= fd_get_device_rev,
 	.get_device_type	= fd_get_device_type,
+	.get_inquiry_prod	= fd_get_inquiry_prod,
+	.get_inquiry_rev	= fd_get_inquiry_rev,
 	.get_dma_length		= fd_get_dma_length,
 	.get_max_sectors	= fd_get_max_sectors,
 	.get_queue_depth	= fd_get_queue_depth,
@@ -1211,7 +1202,6 @@ static struct se_subsystem_api fileio_template = {
 };
 
 static struct se_subsystem_api_cdb fileio_cdb_template = {
-	.emulate_inquiry	= fd_emulate_inquiry,
 	.emulate_read_cap	= fd_emulate_read_cap,
 	.emulate_read_cap16	= fd_emulate_read_cap16,
 	.emulate_unmap		= fd_emulate_unmap,
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index d999f10..4880891 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -340,24 +340,6 @@ static void *iblock_allocate_request(
 	return (void *)ib_req;
 }
 
-static int iblock_emulate_inquiry(struct se_task *task)
-{
-	unsigned char prod[64], se_location[128];
-	struct se_cmd *cmd = TASK_CMD(task);
-	struct iblock_dev *ibd = task->se_dev->dev_ptr;
-	struct se_hba *hba = task->se_dev->se_hba;
-
-	memset(prod, 0, 64);
-	memset(se_location, 0, 128);
-
-	sprintf(prod, "IBLOCK");
-	sprintf(se_location, "%u_%u_%u", hba->hba_id, ibd->ibd_major,
-		ibd->ibd_minor);
-
-	return transport_generic_emulate_inquiry(cmd, TYPE_DISK, prod,
-		IBLOCK_VERSION, se_location);
-}
-
 static unsigned long long iblock_emulate_read_cap_with_block_size(
 	struct se_device *dev,
 	struct block_device *bd,
@@ -1029,6 +1011,16 @@ static u32 iblock_get_device_type(struct se_device *dev)
 	return TYPE_DISK;
 }
 
+static char *iblock_get_inquiry_rev(struct se_device *dev)
+{
+	return IBLOCK_VERSION;
+}
+
+static char *iblock_get_inquiry_prod(struct se_device *dev)
+{
+	return "IBLOCK";
+}
+
 static u32 iblock_get_dma_length(u32 task_size, struct se_device *dev)
 {
 	return PAGE_SIZE;
@@ -1123,6 +1115,8 @@ static struct se_subsystem_api iblock_template = {
 	.get_blocksize		= iblock_get_blocksize,
 	.get_device_rev		= iblock_get_device_rev,
 	.get_device_type	= iblock_get_device_type,
+	.get_inquiry_prod	= iblock_get_inquiry_prod,
+	.get_inquiry_rev	= iblock_get_inquiry_rev,
 	.get_dma_length		= iblock_get_dma_length,
 	.get_max_sectors	= iblock_get_max_sectors,
 	.get_queue_depth	= iblock_get_queue_depth,
@@ -1131,7 +1125,6 @@ static struct se_subsystem_api iblock_template = {
 };
 
 static struct se_subsystem_api_cdb iblock_cdb_template = {
-	.emulate_inquiry	= iblock_emulate_inquiry,
 	.emulate_read_cap	= iblock_emulate_read_cap,
 	.emulate_read_cap16	= iblock_emulate_read_cap16,
 	.emulate_unmap		= iblock_emulate_unmap,
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c
index 374cd16..e29fd09 100644
--- a/drivers/target/target_core_rd.c
+++ b/drivers/target/target_core_rd.c
@@ -385,28 +385,6 @@ static void *rd_allocate_request(
 	return (void *)rd_req;
 }
 
-/*	rd_emulate_inquiry():
- *
- *
- */
-static int rd_emulate_inquiry(struct se_task *task)
-{
-	unsigned char prod[64], se_location[128];
-	struct rd_dev *rd_dev = task->se_dev->dev_ptr;
-	struct se_cmd *cmd = TASK_CMD(task);
-	struct se_hba *hba = task->se_dev->se_hba;
-
-	memset(prod, 0, 64);
-	memset(se_location, 0, 128);
-
-	sprintf(prod, "RAMDISK-%s", (rd_dev->rd_direct) ? "DR" : "MCP");
-	sprintf(se_location, "%u_%u", hba->hba_id, rd_dev->rd_dev_id);
-
-	return transport_generic_emulate_inquiry(cmd, TYPE_DISK, prod,
-			(hba->transport->do_se_mem_map) ? RD_DR_VERSION :
-			RD_MCP_VERSION, se_location);
-}
-
 /*	rd_emulate_read_cap():
  *
  *
@@ -1338,6 +1316,20 @@ static u32 rd_get_device_type(struct se_device *dev)
 	return TYPE_DISK;
 }
 
+static char *rd_get_inquiry_prod(struct se_device *dev)
+{
+	struct rd_dev *rd_dev = dev->dev_ptr;
+
+	return (rd_dev->rd_direct) ? "RAMDISK-DR" : "RAMDISK-MCP";
+}
+
+static char *rd_get_inquiry_rev(struct se_device *dev)
+{
+	struct rd_dev *rd_dev = dev->dev_ptr;
+
+	return (rd_dev->rd_direct) ? RD_DR_VERSION : RD_MCP_VERSION;
+}
+
 /*	rd_get_dma_length(): (Part of se_subsystem_api_t template)
  *
  *
@@ -1406,6 +1398,8 @@ static struct se_subsystem_api rd_dr_template = {
 	.get_blocksize		= rd_get_blocksize,
 	.get_device_rev		= rd_get_device_rev,
 	.get_device_type	= rd_get_device_type,
+	.get_inquiry_prod	= rd_get_inquiry_prod,
+	.get_inquiry_rev	= rd_get_inquiry_rev,
 	.get_dma_length		= rd_get_dma_length,
 	.get_max_sectors	= rd_get_max_sectors,
 	.get_queue_depth	= rd_get_queue_depth,
@@ -1447,6 +1441,8 @@ static struct se_subsystem_api rd_mcp_template = {
 	.get_blocksize		= rd_get_blocksize,
 	.get_device_rev		= rd_get_device_rev,
 	.get_device_type	= rd_get_device_type,
+	.get_inquiry_prod	= rd_get_inquiry_prod,
+	.get_inquiry_rev	= rd_get_inquiry_rev,
 	.get_dma_length		= rd_get_dma_length,
 	.get_max_sectors	= rd_get_max_sectors,
 	.get_queue_depth	= rd_get_queue_depth,
@@ -1455,7 +1451,6 @@ static struct se_subsystem_api rd_mcp_template = {
 };
 
 static struct se_subsystem_api_cdb rd_cdb_template = {
-	.emulate_inquiry	= rd_emulate_inquiry,
 	.emulate_read_cap	= rd_emulate_read_cap,
 	.emulate_read_cap16	= rd_emulate_read_cap16,
 	.emulate_unmap		= NULL,
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index e678686..a49c190 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -4495,8 +4495,7 @@ extern int transport_generic_emulate_inquiry(
 	struct se_cmd *cmd,
 	unsigned char type,
 	unsigned char *prod,
-	unsigned char *version,
-	unsigned char *se_location)
+	unsigned char *version)
 {
 	struct se_device *dev = SE_DEV(cmd);
 	struct se_lun *lun = SE_LUN(cmd);
@@ -4507,8 +4506,8 @@ extern int transport_generic_emulate_inquiry(
 	struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
 	unsigned char *buf = (unsigned char *) T_TASK(cmd)->t_task_buf;
 	unsigned char *cdb = T_TASK(cmd)->t_task_cdb;
-	unsigned char *iqn_sn, binary, binary_new;
-	u32 prod_len, iqn_sn_len, se_location_len;
+	unsigned char binary, binary_new;
+	u32 prod_len;
 	u32 unit_serial_len, off = 0;
 	int i;
 	u16 len = 0, id_len;
@@ -4599,19 +4598,28 @@ after_tpgs:
 	switch (cdb[2]) {
 	case 0x00: /* supported vital product data pages */
 		buf[1] = 0x00;
-		buf[3] = 3;
 		if (cmd->data_length < 8)
 			return 0;
 		buf[4] = 0x0;
-		buf[5] = 0x80;
-		buf[6] = 0x83;
-		buf[7] = 0x86;
-		len = 3;
+		/*
+		 * Only report the INQUIRY EVPD=1 pages after a valid NAA
+		 * Registered Extended LUN WWN has been set via ConfigFS
+		 * during device creation/restart.
+		 */
+		if (dev->se_sub_dev->su_dev_flags &
+					SDF_EMULATED_VPD_UNIT_SERIAL) {
+			buf[3] = 3;
+			buf[5] = 0x80;
+			buf[6] = 0x83;
+			buf[7] = 0x86;
+			len = 3;
+		}
 		break;
 	case 0x80: /* unit serial number */
 		buf[1] = 0x80;
 		if (dev->se_sub_dev->su_dev_flags &
 					SDF_EMULATED_VPD_UNIT_SERIAL) {
+
 			unit_serial_len =
 				strlen(&DEV_T10_WWN(dev)->unit_serial[0]);
 			unit_serial_len++; /* For NULL Terminator */
@@ -4622,23 +4630,9 @@ after_tpgs:
 			}
 			len += sprintf((unsigned char *)&buf[4], "%s",
 				&DEV_T10_WWN(dev)->unit_serial[0]);
-		 } else {
-			iqn_sn = transport_get_iqn_sn();
-			iqn_sn_len = strlen(iqn_sn);
-			iqn_sn_len++; /* For ":" */
-			se_location_len = strlen(se_location);
-			se_location_len++; /* For NULL Terminator */
-
-			if (((len + 4) + (iqn_sn_len + se_location_len)) >
-					cmd->data_length) {
-				len += (iqn_sn_len + se_location_len);
-				goto set_len;
-			}
-			len += sprintf((unsigned char *)&buf[4], "%s:%s",
-				iqn_sn, se_location);
+			len++; /* Extra Byte for NULL Terminator */
+			buf[3] = len;
 		}
-		len++; /* Extra Byte for NULL Terminator */
-		buf[3] = len;
 		break;
 	case 0x83:
 		/*
@@ -4721,21 +4715,6 @@ check_t10_vend_desc:
 			id_len += sprintf((unsigned char *)&buf[off+12],
 					"%s:%s", prod,
 					&DEV_T10_WWN(dev)->unit_serial[0]);
-		} else {
-			iqn_sn = transport_get_iqn_sn();
-			iqn_sn_len = strlen(iqn_sn);
-			iqn_sn_len++; /* For ":" */
-			se_location_len = strlen(se_location);
-			se_location_len++; /* For NULL Terminator */
-
-			if ((len + (id_len + 4) + (prod_len + iqn_sn_len +
-					se_location_len)) > cmd->data_length) {
-				len += (prod_len + iqn_sn_len +
-						se_location_len);
-				goto check_port;
-			}
-			id_len += sprintf((unsigned char *)&buf[off+12],
-				"%s:%s:%s", prod, iqn_sn, se_location);
 		}
 		buf[off] = 0x2; /* ASCII */
 		buf[off+1] = 0x1; /* T10 Vendor ID */
@@ -5574,8 +5553,12 @@ int transport_emulate_control_cdb(struct se_task *task)
 
 	switch (T_TASK(cmd)->t_task_cdb[0]) {
 	case INQUIRY:
-		if (api_cdb->emulate_inquiry(task) < 0)
-			return PYX_TRANSPORT_INVALID_CDB_FIELD;
+		ret = transport_generic_emulate_inquiry(cmd,
+				TRANSPORT(dev)->get_device_type(dev),
+				TRANSPORT(dev)->get_inquiry_prod(dev),
+				TRANSPORT(dev)->get_inquiry_rev(dev));
+		if (ret < 0)
+			return ret;
 		break;
 	case READ_CAPACITY:
 		ret = api_cdb->emulate_read_cap(task);	
diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h
index 8e59144..a949dab 100644
--- a/include/target/target_core_transport.h
+++ b/include/target/target_core_transport.h
@@ -228,8 +228,7 @@ extern void transport_stop_all_task_timers(struct se_cmd *);
 extern int transport_execute_tasks(struct se_cmd *);
 extern unsigned char transport_asciihex_to_binaryhex(unsigned char val[2]);
 extern int transport_generic_emulate_inquiry(struct se_cmd *, unsigned char,
-					unsigned char *, unsigned char *,
-					unsigned char *);
+					unsigned char *, unsigned char *);
 extern int transport_generic_emulate_readcapacity(struct se_cmd *, u32);
 extern int transport_generic_emulate_readcapacity_16(struct se_cmd *,
 							unsigned long long);
@@ -319,7 +318,6 @@ struct se_mem {
  * subsystem plugins.for those CDBs that cannot be emulated generically.
  */
 struct se_subsystem_api_cdb {
-	int (*emulate_inquiry)(struct se_task *);
 	int (*emulate_read_cap)(struct se_task *);
 	int (*emulate_read_cap16)(struct se_task *);
 	int (*emulate_unmap)(struct se_task *);
@@ -554,6 +552,14 @@ struct se_subsystem_api {
 	 */
 	u32 (*get_device_type)(struct se_device *);
 	/*
+	 * Used to obtain INQUIRY Product field field
+	 */
+	char *(*get_inquiry_prod)(struct se_device *);
+	/*
+	 * Used to obtain INQUIRY Production revision field
+	 */
+	char *(*get_inquiry_rev)(struct se_device *);
+	/*
 	 * get_dma_length():
 	 */
 	u32 (*get_dma_length)(u32, struct se_device *);
-- 
1.5.6.5

--
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


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux