[Stgt-devel] [PATCH] return sense data

Pete Wyckoff pw
Sun Feb 25 01:24:35 CET 2007


It is legal to return both data and sense data.  Modify iscsi to do this.
Let target and scsi generate sense information to return through the task.

Signed-off-by: Pete Wyckoff <pw at osc.edu>
---

 usr/driver.h       |    2 +-
 usr/iscsi/iscsid.c |   24 +++++++++++++++++++++---
 usr/iscsi/iscsid.h |    3 +++
 usr/target.c       |   20 +++++++++++---------
 usr/target.h       |    2 ++
 usr/tgtif.c        |    3 ++-
 6 files changed, 40 insertions(+), 14 deletions(-)

diff --git a/usr/driver.h b/usr/driver.h
index 764c53a..0d9fc02 100644
--- a/usr/driver.h
+++ b/usr/driver.h
@@ -18,7 +18,7 @@ struct tgt_driver {
 	int (*scsi_inquiry)(struct tgt_device *, int, uint8_t *, uint8_t *,
 			    uint8_t *, int *);
 	int (*cmd_end_notify)(uint64_t nid, int len, int result, int rw, uint64_t addr,
-			      uint64_t tag);
+			      uint64_t tag, uint8_t *sense, uint8_t senselen);
 	int (*mgmt_end_notify)(uint64_t nid, uint64_t mid, int result);
 
 	struct backedio_template *default_bdt;
diff --git a/usr/iscsi/iscsid.c b/usr/iscsi/iscsid.c
index eefa8b1..8862523 100644
--- a/usr/iscsi/iscsid.c
+++ b/usr/iscsi/iscsid.c
@@ -753,6 +753,22 @@ static int iscsi_cmd_rsp_build(struct iscsi_task *task)
 	rsp->exp_cmdsn = cpu_to_be32(conn->session->exp_cmd_sn);
 	rsp->max_cmdsn = cpu_to_be32(conn->session->exp_cmd_sn + MAX_QUEUE_CMD);
 
+	dprintf("len %d senselen %d\n", task->len, task->senselen);
+
+	/* Tack on sense to response cdb. */
+	if (task->senselen) {
+		uint16_t len = task->senselen;
+		if (len > sizeof(conn->sense_buffer)-2)
+			len = sizeof(conn->sense_buffer) - 2;
+		memcpy(&conn->sense_buffer[2], task->sense, len);
+		conn->sense_buffer[0] = (len & 0xff00) >> 8;
+		conn->sense_buffer[1] = (len & 0x00ff);
+		dprintf("len+2 %d\n", len+2);
+		hton24(rsp->dlength, len+2);
+		conn->rsp.data = conn->sense_buffer;
+		conn->rsp.datasize = len+2;
+	}
+
 	return 0;
 }
 
@@ -877,13 +893,13 @@ static void iscsi_free_cmd_task(struct iscsi_task *task)
 }
 
 int iscsi_scsi_cmd_done(uint64_t nid, int len, int result, int rw, uint64_t addr,
-			uint64_t tag)
+			uint64_t tag, uint8_t *sense, uint8_t senselen)
 {
 	struct iscsi_session *session;
 	struct iscsi_task *task;
 
-	dprintf("%" PRIu64 " %d %d %d %" PRIx64 " %" PRIx64 "\n", nid,
-		len, result, rw, addr, tag);
+	dprintf("%" PRIu64 " %d %d %d %" PRIx64 " %" PRIx64 " senselen %d\n",
+	        nid, len, result, rw, addr, tag, senselen);
 	session = session_lookup(nid);
 	if (!session)
 		return -EINVAL;
@@ -913,6 +929,8 @@ found:
 	task->result = result;
 	task->len = len;
 	task->rw = rw;
+	task->sense = sense;
+	task->senselen = senselen;
 
 	list_add_tail(&task->c_list, &task->conn->tx_clist);
 	tgt_event_modify(task->conn->fd, EPOLLIN | EPOLLOUT);
diff --git a/usr/iscsi/iscsid.h b/usr/iscsi/iscsid.h
index c4b23d9..bc6ec39 100644
--- a/usr/iscsi/iscsid.h
+++ b/usr/iscsi/iscsid.h
@@ -103,6 +103,8 @@ struct iscsi_task {
 	int result;
 	int len;
 	int rw;
+	uint8_t *sense;
+	uint8_t senselen;
 
 	int offset;
 	int data_sn;
@@ -146,6 +148,7 @@ struct iscsi_connection {
 	struct iscsi_pdu req;
 	void *req_buffer;
 	struct iscsi_pdu rsp;
+	uint8_t sense_buffer[252];  /* architectural limit */
 	void *rsp_buffer;
 	unsigned char *rx_buffer;
 	unsigned char *tx_buffer;
diff --git a/usr/target.c b/usr/target.c
index 6cb69ce..51b5106 100644
--- a/usr/target.c
+++ b/usr/target.c
@@ -463,13 +463,15 @@ int target_cmd_queue(uint64_t nid, uint8_t *scb, int scblen, uint8_t rw,
 
 		cmd_post_perform(q, cmd);
 
-		dprintf("%" PRIx64 " %x %" PRIx64 " %" PRIu64 " %u %d %d\n",
-			tag, scb[0], cmd->uaddr, cmd->offset, cmd->len, result, cmd->async);
+		dprintf("%" PRIx64 " %x %lx %" PRIu64 " %d %d %d senselen %d\n",
+			tag, scb[0], cmd->uaddr, cmd->offset, cmd->len, result,
+			cmd->async, cmd->senselen);
 
 		set_cmd_processed(cmd);
 		if (!cmd->async)
 			tgt_drivers[target->lid]->cmd_end_notify(nid, cmd->len, result,
-								 cmd->rw, cmd->uaddr, tag);
+								 cmd->rw, cmd->uaddr, tag,
+								 cmd->sense, cmd->senselen);
 	} else {
 		set_cmd_queued(cmd);
 		dprintf("blocked %" PRIx64 " %x %" PRIu64 " %d\n",
@@ -490,7 +492,7 @@ void target_cmd_io_done(void *key, int result)
 	tgt_drivers[cmd->c_target->lid]->cmd_end_notify(cmd->cmd_nexus_id,
 							cmd->len, result,
 							cmd->rw, cmd->uaddr,
-							cmd->tag);
+							cmd->tag, NULL, 0);
 	return;
 }
 
@@ -498,7 +500,6 @@ static void post_cmd_done(struct tgt_cmd_queue *q)
 {
 	struct scsi_cmd *cmd, *tmp;
 	int enabled, result;
-	int (* notify_fn)(uint64_t, int, int, int, uint64_t, uint64_t);
 
 	list_for_each_entry_safe(cmd, tmp, &q->queue, qlist) {
 		enabled = cmd_enabled(q, cmd);
@@ -515,9 +516,10 @@ static void post_cmd_done(struct tgt_cmd_queue *q)
 			cmd_post_perform(q, cmd);
 			set_cmd_processed(cmd);
 			if (!cmd->async) {
-				notify_fn = tgt_drivers[cmd->c_target->lid]->cmd_end_notify;
-				notify_fn(cmd->cmd_nexus_id, cmd->len, result, cmd->rw,
-					  cmd->uaddr, cmd->tag);
+				tgt_drivers[cmd->c_target->lid]->cmd_end_notify(
+					cmd->cmd_nexus_id, cmd->len, result,
+					cmd->rw, cmd->uaddr, cmd->tag,
+					cmd->sense, cmd->senselen);
 			}
 		} else
 			break;
@@ -613,7 +615,7 @@ static int abort_cmd(struct target* target, struct mgmt_req *mreq,
 	} else {
 		__cmd_done(target, cmd);
 		tgt_drivers[cmd->c_target->lid]->cmd_end_notify(cmd->cmd_nexus_id, 0,
-								TASK_ABORTED, 0, 0, cmd->tag);
+								TASK_ABORTED, 0, 0, cmd->tag, NULL, 0);
 	}
 	return err;
 }
diff --git a/usr/target.h b/usr/target.h
index e90b094..37da8c5 100644
--- a/usr/target.h
+++ b/usr/target.h
@@ -98,6 +98,8 @@ struct scsi_cmd {
 	uint8_t rw;
 	int async;
 	struct mgmt_req *mreq;
+	uint8_t *sense;    /* output values from target */
+	uint8_t senselen;
 };
 
 enum {
diff --git a/usr/tgtif.c b/usr/tgtif.c
index 4c22863..b87a5ac 100644
--- a/usr/tgtif.c
+++ b/usr/tgtif.c
@@ -101,7 +101,8 @@ int kspace_send_tsk_mgmt_res(uint64_t nid, uint64_t mid, int result)
 }
 
 int kspace_send_cmd_res(uint64_t nid, int len, int result,
-			int rw, uint64_t addr, uint64_t tag)
+			int rw, uint64_t addr, uint64_t tag,
+			uint8_t *sense, uint8_t senselen)
 {
 	struct tgt_event ev;
 



More information about the stgt mailing list