[PATCH] Add new module entry points for configuration

Mark Harvey markh794
Sat Jun 2 09:25:52 CEST 2007


Add new module entry points.
  <module>_lu_init(struct scsi_lu *lu) - called at setup time.
  <module>_lu_exit(struct scsi_lu *lu) - called at shutdown time.
  <module>_lu_config(struct scsi_lu *lu) - Any module unique configuration.

Moved logical unit configuration from target -> <module>
  Along with above entry point <module>_lu_config(), will allow module
  specific configuration.
  No new functionality added yet.

Add a dump_cdb(struct scsi_cmd *cmd) - Called from spc_illegal_op()

Update - All modules use common INQUIRY routine.

Signed-off-by: Mark Harvey <markh794 at gmail.com>

diff --git a/usr/mmc.c b/usr/mmc.c
index e9cc479..8154ede 100644
--- a/usr/mmc.c
+++ b/usr/mmc.c
@@ -121,11 +121,32 @@ static int mmc_read_capacity(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 }
 
+static int mmc_lu_init(struct scsi_lu *lu)
+{
+	if (spc_lu_init(lu))
+		return -ENOMEM;
+
+	memcpy(lu->attributes->product_ident, "VIRTUAL-CDROM", 16);
+	lu->attributes->sense_format = 0;
+	lu->attributes->version_desc[0] = 0x02A0; /* MMC3, no version claimed */
+	lu->attributes->version_desc[1] = 0x0960; /* iSCSI */
+	lu->attributes->version_desc[2] = 0x0300; /* SPC-3 */
+
+	return 0;
+}
+
+static int mmc_lu_exit(struct scsi_lu *lu)
+{
+	return 0;
+}
+
 struct device_type_template mmc_template = {
-	.type	= TYPE_ROM,
-	.name	= "cdrom/dvd",
-	.pid	= "VIRTUAL-CDROM",
-	.ops	= {
+	.type		= TYPE_ROM,
+	.name		= "cdrom/dvd",
+	.lu_init	= mmc_lu_init,
+	.lu_exit	= mmc_lu_exit,
+	.lu_config	= spc_lu_config,
+	.ops		= {
 		{spc_test_unit,},
 		{spc_illegal_op,},
 		{spc_illegal_op,},
diff --git a/usr/osd.c b/usr/osd.c
index 46bf0a0..62c0082 100644
--- a/usr/osd.c
+++ b/usr/osd.c
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA
  */
+#include <errno.h>
 #include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -33,101 +34,6 @@
 #include "scsi.h"
 #include "spc.h"
 
-#define PRODUCT_ID	"OSD"
-#define PRODUCT_REV	"0"
-
-static int osd_inquiry(int host_no, struct scsi_cmd *cmd)
-{
-	uint8_t *data, *scb = cmd->scb;
-	int len, ret = SAM_STAT_CHECK_CONDITION;
-	unsigned char key = ILLEGAL_REQUEST, asc = 0x25;
-
-	/* EVPD means need a page code */
-	if ((scb[1] & 0x3) == 0 && scb[2] != 0)
-		goto sense;
-
-	data = valloc(pagesize);
-	if (!data) {
-		key = HARDWARE_ERROR;
-		asc = 0;
-		goto sense;
-	}
-	memset(data, 0, pagesize);
-
-	dprintf("%x %x\n", scb[1], scb[2]);
-
-	data[0] = TYPE_OSD;
-	if (!cmd->dev)
-		data[0] = TYPE_NO_LUN;
-
-	if ((scb[1] & 0x1) == 0) {
-		data[2] = 5;  /* modern version */
-		data[3] = 0x02;  /* modern response format */
-		data[7] = 0x02;  /* support command queueing */
-		memset(data + 8, 0x20, 28);
-		memcpy(data + 8,
-		       VENDOR_ID, min_t(size_t, strlen(VENDOR_ID), 8));
-		memcpy(data + 16,
-		       PRODUCT_ID, min_t(size_t, strlen(PRODUCT_ID), 16));
-		memcpy(data + 32,
-		       PRODUCT_REV, min_t(size_t, strlen(PRODUCT_REV), 4));
-		len = 36;
-		if (cmd->dev) {
-			data[58] = 0x03;
-			data[59] = 0x40;  /* osd */
-			data[60] = 0x09;
-			data[61] = 0x60;  /* iscsi */
-			data[62] = 0x03;
-			data[63] = 0x00;  /* spc3 */
-			len = 64;
-		}
-		data[4] = len - 5;  /* additional length */
-		ret = SAM_STAT_GOOD;
-	} else {
-		if (!cmd->dev)
-			goto sense;
-
-		data[1] = scb[2];
-		if (scb[2] == 0x0) {
-			/* supported VPD pages */
-			data[3] = 3;
-			data[4] = 0x0;
-			data[5] = 0x80;
-			data[6] = 0x83;
-			len = 7;
-			ret = SAM_STAT_GOOD;
-		} else if (scb[2] == 0x80) {
-			/* unit serial number "    " */
-			data[3] = 4;
-			memset(data + 4, 0x20, 4);
-			len = 8;
-			ret = SAM_STAT_GOOD;
-		} else if (scb[2] == 0x83) {
-			/* device identification */
-			data[3] = SCSI_ID_LEN + 4;
-			data[4] = 0x1;
-			data[5] = 0x1;
-			data[7] = SCSI_ID_LEN;
-			if (cmd->dev)
-				memcpy(data + 8, cmd->dev->scsi_id, SCSI_ID_LEN);
-			len = SCSI_ID_LEN + 8;
-			ret = SAM_STAT_GOOD;
-		}
-	}
-
-	if (ret != SAM_STAT_GOOD)
-		goto sense;
-
-	cmd->len = min_t(int, len, scb[4]);
-	cmd->uaddr = (unsigned long) data;
-
-	return SAM_STAT_GOOD;
-sense:
-	sense_data_build(cmd, key, asc, 0);
-	cmd->len = 0;
-	return SAM_STAT_CHECK_CONDITION;
-}
-
 static int osd_varlen_cdb(int host_no, struct scsi_cmd *cmd)
 {
 	unsigned char key = ILLEGAL_REQUEST, asc = 0x25;
@@ -145,22 +51,37 @@ static int osd_varlen_cdb(int host_no, struct scsi_cmd *cmd)
 	return cmd->c_target->bst->bs_cmd_submit(cmd);
 }
 
-static void device_osd_init(struct scsi_lu *lu)
+static int osd_lu_init(struct scsi_lu *lu)
+{
+	if (spc_lu_init(lu))
+		return -ENOMEM;
+
+	memcpy(lu->attributes->product_ident, "OSD", 16);
+	lu->attributes->sense_format = 1;
+	lu->attributes->version_desc[0] = 0x0340; /* OSD */
+	lu->attributes->version_desc[1] = 0x0960; /* iSCSI */
+	lu->attributes->version_desc[2] = 0x0300; /* SPC-3 */
+
+	return 0;
+}
+
+static int osd_lu_exit(struct scsi_lu *lu)
 {
-	lu->d_sense = 1;
+	return 0;
 }
 
 struct device_type_template osd_template = {
 	.type		= TYPE_OSD,
 	.name		= "osd",
-	.device_init	= device_osd_init,
+	.lu_init	= osd_lu_init,
+	.lu_exit	= osd_lu_exit,
 	.ops		= {
 		[0x00 ... 0x0f] = {spc_illegal_op},
 
 		/* 0x10 */
 		{spc_illegal_op,},
 		{spc_illegal_op,},
-		{osd_inquiry,},
+		{spc_inquiry,},
 		{spc_illegal_op,},
 		{spc_illegal_op,},
 		{spc_illegal_op,},
diff --git a/usr/sbc.c b/usr/sbc.c
index a22d3b0..8f981d3 100644
--- a/usr/sbc.c
+++ b/usr/sbc.c
@@ -337,11 +337,31 @@ sense:
 	return SAM_STAT_CHECK_CONDITION;
 }
 
+static int sbc_lu_init(struct scsi_lu *lu)
+{
+	if (spc_lu_init(lu))
+		return -ENOMEM;
+
+	memcpy(lu->attributes->product_ident, "VIRTUAL-DISK", 16);
+	lu->attributes->version_desc[0] = 0x04C0; /* SBC-3 no version claimed */
+	lu->attributes->version_desc[1] = 0x0960; /* iSCSI */
+	lu->attributes->version_desc[2] = 0x0300; /* SPC-3 */
+
+	return 0;
+}
+
+static int sbc_lu_exit(struct scsi_lu *lu)
+{
+	return 0;
+}
+
 struct device_type_template sbc_template = {
-	.type	= TYPE_DISK,
-	.name	= "disk",
-	.pid	= "VIRTUAL-DISK",
-	.ops	= {
+	.type		= TYPE_DISK,
+	.name		= "disk",
+	.lu_init	= sbc_lu_init,
+	.lu_exit	= sbc_lu_exit,
+	.lu_config	= spc_lu_config,
+	.ops		= {
 		{spc_test_unit,},
 		{spc_illegal_op,},
 		{spc_illegal_op,},
diff --git a/usr/scsi.c b/usr/scsi.c
index 1a6929f..728dfe9 100644
--- a/usr/scsi.c
+++ b/usr/scsi.c
@@ -40,7 +40,7 @@
 
 void sense_data_build(struct scsi_cmd *cmd, uint8_t key, uint8_t asc, uint8_t asq)
 {
-	if (cmd->dev && cmd->dev->d_sense) {
+	if (cmd->dev && cmd->dev->attributes->sense_format) {
 		/* descriptor format */
 
 		cmd->sense_buffer[0] = 0x72;  /* current, not deferred */
@@ -121,3 +121,4 @@ int scsi_cmd_perform(int host_no, struct scsi_cmd *cmd)
 	unsigned char op = cmd->scb[0];
 	return cmd->c_target->dev_type_template.ops[op].cmd_perform(host_no, cmd);
 }
+
diff --git a/usr/spc.c b/usr/spc.c
index b922a45..32a9ff7 100644
--- a/usr/spc.c
+++ b/usr/spc.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA
  */
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -27,12 +28,15 @@
 #include "list.h"
 #include "util.h"
 #include "tgtd.h"
+#include "parser.h"
 #include "target.h"
 #include "driver.h"
+#include "tgtadm_error.h"
 #include "scsi.h"
 #include "spc.h"
 
 #define PRODUCT_REV	"0"
+#define BLK_SHIFT	9
 
 int spc_inquiry(int host_no, struct scsi_cmd *cmd)
 {
@@ -40,7 +44,7 @@ int spc_inquiry(int host_no, struct scsi_cmd *cmd)
 	uint8_t *data;
 	uint8_t *scb = cmd->scb;
 	unsigned char device_type = cmd->c_target->dev_type_template.type;
-	char *product_id = cmd->c_target->dev_type_template.pid;
+	struct lu_phy_attr *attributes = cmd->dev->attributes;
 	unsigned char key = ILLEGAL_REQUEST, asc = 0x24;
 
 	if (((scb[1] & 0x3) == 0x3) || (!(scb[1] & 0x3) && scb[2]))
@@ -57,22 +61,21 @@ int spc_inquiry(int host_no, struct scsi_cmd *cmd)
 	dprintf("%x %x\n", scb[1], scb[2]);
 
 	if (!(scb[1] & 0x3)) {
+		int i;
 		data[0] = device_type;
-		data[2] = 4;
+		data[1] = (attributes->is_removable) ? 0x80 : 0;
+		data[2] = 5;	/* SPC-3 */
 		data[3] = 0x42;
-		data[4] = 59;
 		data[7] = 0x02;
 		memset(data + 8, 0x20, 28);
-		strncpy((char *)data + 8, VENDOR_ID, 8);
-		strncpy((char *)data + 16, product_id, 16);
-		strncpy((char *)data + 32, PRODUCT_REV, 4);
-		data[58] = 0x03;
-		data[59] = 0x20;
-		data[60] = 0x09;
-		data[61] = 0x60;
-		data[62] = 0x03;
-		data[63] = 0x00;
-		len = 64;
+		strncpy((char *)data + 8, attributes->vendor_ident, 8);
+		strncpy((char *)data + 16, attributes->product_ident, 16);
+		strncpy((char *)data + 32, attributes->product_rev, 4);
+		for (i=0, len=58; i < VERSION_DESCRIPTOR_LEN; i++, len += 2) {
+			data[len] = (attributes->version_desc[i] >> 8) & 0xff;
+			data[len+1] = attributes->version_desc[i] & 0xff;
+		}
+		data[4] = len - 5;	/* Additional Length */
 		ret = SAM_STAT_GOOD;
 	} else if (scb[1] & 0x2) {
 		/* CmdDt bit is set */
@@ -101,13 +104,13 @@ int spc_inquiry(int host_no, struct scsi_cmd *cmd)
 			len = 4 + SCSI_SN_LEN;
 			ret = SAM_STAT_GOOD;
 
-			if (cmd->dev && strlen(cmd->dev->scsi_sn)) {
+			if (cmd->dev && strlen(cmd->dev->attributes->scsi_sn)) {
 				uint8_t *p;
 				char *q;
 
 				p = data + 4 + tmp - 1;
-				q = cmd->dev->scsi_sn + SCSI_SN_LEN - 1;
-
+				q = cmd->dev->attributes->scsi_sn +
+								SCSI_SN_LEN - 1;
 				for (; tmp > 0; tmp--, q)
 					*(p--) = *(q--);
 			}
@@ -120,7 +123,8 @@ int spc_inquiry(int host_no, struct scsi_cmd *cmd)
 			data[5] = 0x1;
 			data[7] = tmp;
 			if (cmd->dev)
-				strncpy((char *) data + 8, cmd->dev->scsi_id,
+				strncpy((char *) data + 8,
+					cmd->dev->attributes->scsi_id,
 				        SCSI_ID_LEN);
 			len = tmp + 8;
 			ret = SAM_STAT_GOOD;
@@ -238,9 +242,98 @@ int spc_request_sense(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_GOOD;
 }
 
+void dump_cdb(struct scsi_cmd *cmd)
+{
+	uint8_t *cdb = cmd->scb;
+
+	switch(cmd->scb_len) {
+	case 6:
+		dprintf("SCSI CMD: %02x %02x %02x %02x %02d %02x",
+			cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5]);
+		break;
+	case 10:
+		dprintf("SCSI CMD: %02x %02x %02x %02x %02d %02x"
+				" %02x %02x %02x %02x",
+			cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5],
+			cdb[6], cdb[7], cdb[8], cdb[9]);
+		break;
+	case 12:
+		dprintf("SCSI CMD: %02x %02x %02x %02x %02d %02x"
+				" %02x %02x %02x %02x %02x %02x",
+			cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5],
+			cdb[6], cdb[7], cdb[8], cdb[9], cdb[10], cdb[11]);
+		break;
+	case 16:
+		dprintf("SCSI CMD: %02x %02x %02x %02x %02d %02x"
+				" %02x %02x %02x %02x %02x %02x"
+				" %02x %02x %02x %02x",
+			cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5],
+			cdb[6], cdb[7], cdb[8], cdb[9], cdb[10], cdb[11],
+			cdb[12], cdb[13], cdb[14], cdb[15]);
+		break;
+	}
+}
+
 int spc_illegal_op(int host_no, struct scsi_cmd *cmd)
 {
+	dump_cdb(cmd);
 	cmd->len = 0;
 	sense_data_build(cmd, ILLEGAL_REQUEST, 0x20, 0);
 	return SAM_STAT_CHECK_CONDITION;
 }
+
+enum {
+	Opt_scsiid, Opt_scsisn, Opt_err,
+};
+
+static match_table_t tokens = {
+	{Opt_scsiid, "scsi_id=%s"},
+	{Opt_scsisn, "scsi_sn=%s"},
+	{Opt_err, NULL},
+};
+
+int spc_lu_config(struct scsi_lu *lu, char *params) {
+	int err = 0;
+	char *p;
+
+	if (!strncmp("targetOps", params, 9))
+		params = params + 10;
+
+	while ((p = strsep(&params, ",")) != NULL) {
+		substring_t args[MAX_OPT_ARGS];
+		int token;
+		if (!*p)
+			continue;
+		dprintf("*p : %s\n", p);
+		token = match_token(p, tokens, args);
+		switch (token) {
+		case Opt_scsiid:
+			match_strncpy(lu->attributes->scsi_id, &args[0],
+				      sizeof(lu->attributes->scsi_id) - 1);
+			break;
+		case Opt_scsisn:
+			match_strncpy(lu->attributes->scsi_sn, &args[0],
+				      sizeof(lu->attributes->scsi_sn) - 1);
+			break;
+		default:
+			err = TGTADM_INVALID_REQUEST;
+		}
+	}
+	return err;
+}
+
+int spc_lu_init(struct scsi_lu *lu)
+{
+	lu->attributes = zalloc(sizeof(struct lu_phy_attr));
+	if(!lu->attributes)
+		return -ENOMEM;
+
+	memcpy(lu->attributes->vendor_ident, VENDOR_ID, 8);
+	memcpy(lu->attributes->product_rev, "0001", 4);
+	lu->attributes->is_removable = 0;
+	lu->attributes->sense_format = 0;
+	lu->attributes->online = 0;
+	lu->attributes->reset = 1;
+
+	return 0;
+}
diff --git a/usr/spc.h b/usr/spc.h
index f81e74c..1036b70 100644
--- a/usr/spc.h
+++ b/usr/spc.h
@@ -7,5 +7,8 @@ extern int spc_start_stop(int host_no, struct scsi_cmd *cmd);
 extern int spc_test_unit(int host_no, struct scsi_cmd *cmd);
 extern int spc_request_sense(int host_no, struct scsi_cmd *cmd);
 extern int spc_illegal_op(int host_no, struct scsi_cmd *cmd);
+extern int spc_lu_init(struct scsi_lu *lu);
+extern int spc_lu_config(struct scsi_lu *lu, char * params);
+extern void dump_cdb(struct scsi_cmd *cmd);
 
 #endif
diff --git a/usr/target.c b/usr/target.c
index 23f450f..8160359 100644
--- a/usr/target.c
+++ b/usr/target.c
@@ -29,7 +29,6 @@
 #include <sys/socket.h>
 
 #include "list.h"
-#include "parser.h"
 #include "util.h"
 #include "tgtd.h"
 #include "driver.h"
@@ -247,13 +246,19 @@ int tgt_device_create(int tid, uint64_t lun, char *args)
 	lu->lun = lun;
 	lu->lu_state = SCSI_LU_RUNNING;
 
-	snprintf(lu->scsi_id, sizeof(lu->scsi_id),
-		 "deadbeaf%d:%" PRIu64, tid, lun);
-
 	tgt_cmd_queue_init(&lu->cmd_queue);
 
-	if (target->dev_type_template.device_init)
-		target->dev_type_template.device_init(lu);
+	if (target->dev_type_template.lu_init)
+		err = target->dev_type_template.lu_init(lu);
+
+	if(!err) {
+		snprintf(lu->attributes->scsi_id,
+				sizeof(lu->attributes->scsi_id),
+				"deadbeaf%d:%" PRIu64, tid, lun);
+		snprintf(lu->attributes->scsi_sn,
+				sizeof(lu->attributes->scsi_sn),
+				"beaf%d%" PRIu64, tid, lun);
+	}
 
 	list_for_each_entry(pos, &target->device_list, device_siblings) {
 		if (lu->lun < pos->lun)
@@ -262,13 +267,14 @@ int tgt_device_create(int tid, uint64_t lun, char *args)
 	list_add_tail(&lu->device_siblings, &pos->device_siblings);
 
 	dprintf("Add a logical unit %" PRIu64 " to the target %d\n", lun, tid);
-	return 0;
+	return err;
 }
 
 int tgt_device_destroy(int tid, uint64_t lun)
 {
 	struct target *target;
 	struct scsi_lu *lu;
+	int err;
 
 	dprintf("%u %" PRIu64 "\n", tid, lun);
 
@@ -281,12 +287,14 @@ int tgt_device_destroy(int tid, uint64_t lun)
 	if (!list_empty(&lu->cmd_queue.queue) || lu->cmd_queue.active_cmd)
 		return TGTADM_LUN_ACTIVE;
 
+	err = target->dev_type_template.lu_exit(lu);
+
 	free(lu->path);
 	list_del(&lu->device_siblings);
 
 	target->bst->bs_close(lu);
 	free(lu);
-	return 0;
+	return err;
 }
 
 int device_reserve(struct scsi_cmd *cmd)
@@ -339,20 +347,9 @@ int device_reserved(struct scsi_cmd *cmd)
 	return -EBUSY;
 }
 
-enum {
-	Opt_scsiid, Opt_scsisn, Opt_err,
-};
-
-static match_table_t tokens = {
-	{Opt_scsiid, "scsi_id=%s"},
-	{Opt_scsisn, "scsi_sn=%s"},
-	{Opt_err, NULL},
-};
-
 int tgt_device_update(int tid, uint64_t dev_id, char *params)
 {
-	int err = 0;
-	char *p;
+	int err = TGTADM_INVALID_REQUEST;
 	struct target *target;
 	struct scsi_lu *lu;
 
@@ -366,26 +363,8 @@ int tgt_device_update(int tid, uint64_t dev_id, char *params)
 		return TGTADM_NO_LUN;
 	}
 
-	while ((p = strsep(&params, ",")) != NULL) {
-		substring_t args[MAX_OPT_ARGS];
-		int token;
-		if (!*p)
-			continue;
-		token = match_token(p, tokens, args);
-
-		switch (token) {
-		case Opt_scsiid:
-			match_strncpy(lu->scsi_id, &args[0],
-				      sizeof(lu->scsi_id) - 1);
-			break;
-		case Opt_scsisn:
-			match_strncpy(lu->scsi_sn, &args[0],
-				      sizeof(lu->scsi_sn) - 1);
-			break;
-		default:
-			err = TGTADM_INVALID_REQUEST;
-		}
-	}
+	if (target->dev_type_template.lu_config)
+		err = target->dev_type_template.lu_config(lu, params);
 
 	return err;
 }
@@ -474,8 +453,8 @@ int target_cmd_queue(int tid, struct scsi_cmd *cmd)
 		cmd_post_perform(q, cmd);
 
 		dprintf("%" PRIx64 " %x %" PRIx64 " %" PRIu64 " %u %d %d\n",
-			cmd->tag, cmd->scb[0], cmd->uaddr, cmd->offset, cmd->len,
-			result, cmd->async);
+			cmd->tag, cmd->scb[0], cmd->uaddr, cmd->offset,
+			cmd->len, result, cmd->async);
 
 		set_cmd_processed(cmd);
 		if (!cmd->async)
@@ -483,7 +462,8 @@ int target_cmd_queue(int tid, struct scsi_cmd *cmd)
 	} else {
 		set_cmd_queued(cmd);
 		dprintf("blocked %" PRIx64 " %x %" PRIu64 " %d\n",
-			cmd->tag, cmd->scb[0], cmd->dev ? cmd->dev->lun : UINT64_MAX,
+			cmd->tag, cmd->scb[0],
+			cmd->dev ? cmd->dev->lun : UINT64_MAX,
 			q->active_cmd);
 
 		list_add_tail(&cmd->qlist, &q->queue);
@@ -1148,8 +1128,8 @@ int tgt_target_show_all(char *buf, int rest)
 				 _TAB3 "Size: %s\n"
 				 _TAB3 "Backing store: %s\n",
 				 lu->lun,
-				 lu->scsi_id,
-				 lu->scsi_sn,
+				 lu->attributes->scsi_id,
+				 lu->attributes->scsi_sn,
 				 print_disksize(lu->size),
 				 lu->path);
 
diff --git a/usr/tgtadm.c b/usr/tgtadm.c
index e55a785..3d551cc 100644
--- a/usr/tgtadm.c
+++ b/usr/tgtadm.c
@@ -103,6 +103,7 @@ struct option const long_options[] = {
 	{"initiator-address", required_argument, NULL, 'I'},
 	{"user", required_argument, NULL, 'u'},
 	{"password", required_argument, NULL, 'p'},
+	{"params", required_argument, NULL, 'P'},
 
 	{"bus", required_argument, NULL, 'B'},
 	{"target-type", required_argument, NULL, 'Y'},
@@ -110,7 +111,7 @@ struct option const long_options[] = {
 	{NULL, 0, NULL, 0},
 };
 
-static char *short_options = "dhL:o:m:t:s:c:l:n:v:b:T:I:u:p:B:Y:O";
+static char *short_options = "dhL:o:m:t:s:c:l:n:v:b:T:I:u:p:P:B:Y:O";
 
 static void usage(int status)
 {
@@ -355,7 +356,7 @@ int main(int argc, char **argv)
 	int op, total, tid, rest, mode, t_type, ac_dir;
 	uint32_t cid, hostno;
 	uint64_t sid, lun;
-	char *name, *value, *path, *targetname, *params, *address;
+	char *name, *value, *path, *targetname, *params, *address, *targetOps;
 	char *user, *password;
 	char buf[BUFSIZE + sizeof(struct tgtadm_req)];
 	struct tgtadm_req *req;
@@ -365,7 +366,7 @@ int main(int argc, char **argv)
 	t_type = TYPE_DISK;
 	ac_dir = ACCOUNT_TYPE_INCOMING;
 	rest = BUFSIZE;
-	name = value = path = targetname = address = NULL;
+	name = value = path = targetname = address = targetOps = NULL;
 	user = password = NULL;
 
 	memset(buf, 0, sizeof(buf));
@@ -396,6 +397,9 @@ int main(int argc, char **argv)
 		case 'l':
 			lun = strtoull(optarg, NULL, 10);
 			break;
+		case 'P':
+			targetOps = optarg;
+			break;
 		case 'n':
 			name = optarg;
 			break;
@@ -570,6 +574,10 @@ int main(int argc, char **argv)
 	if (password)
 		shprintf(total, params, rest, "%spassword=%s",
 			 rest == BUFSIZE ? "" : ",", password);
+	// Trailing ',' makes parsing params in modules easier..
+	if (targetOps)
+		shprintf(total, params, rest, "%stargetOps %s,",
+			 rest == BUFSIZE ? "" : ",", targetOps);
 
 	req->len = sizeof(*req) + total;
 
diff --git a/usr/tgtadm.h b/usr/tgtadm.h
index fb83753..d53cb40 100644
--- a/usr/tgtadm.h
+++ b/usr/tgtadm.h
@@ -4,31 +4,7 @@
 #define TGT_IPC_NAMESPACE	"TGT_IPC_ABSTRACT_NAMESPACE"
 #define TGT_LLD_NAME_LEN	64
 
-enum tgtadm_errno {
-	TGTADM_SUCCESS,
-	TGTADM_UNKNOWN_ERR,
-	TGTADM_NOMEM,
-	TGTADM_NO_DRIVER,
-	TGTADM_NO_TARGET,
-
-	TGTADM_NO_LUN,
-	TGTADM_NO_SESSION,
-	TGTADM_NO_CONNECTION,
-	TGTADM_TARGET_EXIST,
-	TGTADM_LUN_EXIST,
-
-	TGTADM_ACL_EXIST,
-	TGTADM_USER_EXIST,
-	TGTADM_NO_USER,
-	TGTADM_TOO_MANY_USER,
-	TGTADM_INVALID_REQUEST,
-
-	TGTADM_OUTACCOUNT_EXIST,
-	TGTADM_TARGET_ACTIVE,
-	TGTADM_LUN_ACTIVE,
-	TGTADM_UNSUPPORTED_OPERATION,
-	TGTADM_UNKNOWN_PARAM,
-};
+#include "tgtadm_error.h"
 
 enum tgtadm_op {
 	OP_NEW,
diff --git a/usr/tgtadm_error.h b/usr/tgtadm_error.h
new file mode 100644
index 0000000..319a4ad
--- /dev/null
+++ b/usr/tgtadm_error.h
@@ -0,0 +1,30 @@
+#ifndef TGTADM_ERROR_H
+#define TGTADM_ERROR_H
+
+enum tgtadm_errno {
+	TGTADM_SUCCESS,
+	TGTADM_UNKNOWN_ERR,
+	TGTADM_NOMEM,
+	TGTADM_NO_DRIVER,
+	TGTADM_NO_TARGET,
+
+	TGTADM_NO_LUN,
+	TGTADM_NO_SESSION,
+	TGTADM_NO_CONNECTION,
+	TGTADM_TARGET_EXIST,
+	TGTADM_LUN_EXIST,
+
+	TGTADM_ACL_EXIST,
+	TGTADM_USER_EXIST,
+	TGTADM_NO_USER,
+	TGTADM_TOO_MANY_USER,
+	TGTADM_INVALID_REQUEST,
+
+	TGTADM_OUTACCOUNT_EXIST,
+	TGTADM_TARGET_ACTIVE,
+	TGTADM_LUN_ACTIVE,
+	TGTADM_UNSUPPORTED_OPERATION,
+	TGTADM_UNKNOWN_PARAM,
+};
+
+#endif
diff --git a/usr/tgtd.h b/usr/tgtd.h
index 06e0dd9..f5d5e2f 100644
--- a/usr/tgtd.h
+++ b/usr/tgtd.h
@@ -5,6 +5,7 @@
 
 #define SCSI_ID_LEN	24
 #define SCSI_SN_LEN	8
+#define VERSION_DESCRIPTOR_LEN 8
 
 #define VENDOR_ID	"IET"
 
@@ -29,13 +30,27 @@ struct tgt_cmd_queue {
 	struct list_head queue;
 };
 
+struct lu_phy_attr {
+	char scsi_id[SCSI_ID_LEN];
+	char scsi_sn[SCSI_SN_LEN];
+
+	/* SCSI Inquiry Params */
+	char vendor_ident[9];
+	char product_ident[17];
+	char product_rev[5];
+	uint16_t version_desc[VERSION_DESCRIPTOR_LEN];
+
+	char is_removable;	/* Removable media */
+	char online;		/* Logical Unit online ? */
+	char reset;		/* Power-on or reset has occured */
+	char sense_format;	/* Descrptor format sense data supported */
+};
+
 struct scsi_lu {
 	int fd;
 	uint64_t addr; /* persistent mapped address */
 	uint64_t size;
 	uint64_t lun;
-	char scsi_id[SCSI_ID_LEN];
-	char scsi_sn[SCSI_SN_LEN];
 	char *path;
 
 	/* the list of devices belonging to a target */
@@ -48,7 +63,7 @@ struct scsi_lu {
 	uint64_t reserve_id;
 
 	/* TODO: needs a structure for lots of device parameters */
-	uint8_t d_sense;
+	struct lu_phy_attr *attributes;
 };
 
 struct scsi_cmd {
@@ -121,7 +136,9 @@ struct device_type_template {
 	char *name;
 	char *pid;
 
-	void (*device_init)(struct scsi_lu *dev);
+	int (*lu_init)(struct scsi_lu *lu);
+	int (*lu_exit)(struct scsi_lu *lu);
+	int (*lu_config)(struct scsi_lu *lu, char *arg);
 
 	struct device_type_operations ops[256];
 };
-- 
1.5.1.3


--------------030802070500090204010901--



More information about the stgt mailing list