[PATCH 2/2] target/usb-gadget: store sense information for later REQUEST_SENSE query

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

 



On BOT I can't send the SENSE response back, instead I can only reply
that an error occured.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
---
 drivers/target/target_core_ua.c    |    1 +
 drivers/target/usb-gadget/bot.c    |   49 +++++++++++++++++++++--------------
 drivers/target/usb-gadget/fabric.c |   14 ++++------
 drivers/target/usb-gadget/usbg.h   |    1 -
 4 files changed, 36 insertions(+), 29 deletions(-)

diff --git a/drivers/target/target_core_ua.c b/drivers/target/target_core_ua.c
index 3e12f6b..d9200d9 100644
--- a/drivers/target/target_core_ua.c
+++ b/drivers/target/target_core_ua.c
@@ -183,6 +183,7 @@ int core_scsi3_ua_allocate(
 	smp_mb__after_atomic_inc();
 	return 0;
 }
+EXPORT_SYMBOL_GPL(core_scsi3_ua_allocate);
 
 void core_scsi3_ua_release_all(
 	struct se_dev_entry *deve)
diff --git a/drivers/target/usb-gadget/bot.c b/drivers/target/usb-gadget/bot.c
index b8c6fd1..412e473 100644
--- a/drivers/target/usb-gadget/bot.c
+++ b/drivers/target/usb-gadget/bot.c
@@ -10,6 +10,7 @@
 #include <linux/usb/storage.h>
 
 #include <target/target_core_base.h>
+#include "../target_core_ua.h"
 
 #include "usbg.h"
 
@@ -38,12 +39,35 @@ static void bot_status_complete(struct usb_ep *ep, struct usb_request *req)
 	bot_enqueue_cmd_cbw(fu);
 }
 
+static void bot_enqueue_sense_code(struct f_uas *fu, struct usbg_cmd *cmd)
+{
+	struct bulk_cs_wrap *csw = &fu->bot_status.csw;
+	int ret;
+	u8 *sense;
+
+	/*
+	 * We can't send SENSE as a response. So we take ASC & ASCQ from our
+	 * sense buffer and queue it and hope the host sends a REQUEST_SENSE
+	 * command where it learns why we failed.
+	 */
+	sense = cmd->sense_iu.sense;
+	core_scsi3_ua_allocate(cmd->se_cmd.se_sess->se_node_acl,
+			cmd->unpacked_lun,
+			*(sense + SPC_ASC_KEY_OFFSET),
+			*(sense + SPC_ASCQ_KEY_OFFSET));
+
+	csw->Tag = cmd->bot_tag;
+	csw->Status = US_BULK_STAT_FAIL;
+	fu->bot_status.req->context = cmd;
+	ret = usb_ep_queue(fu->ep_in, fu->bot_status.req, GFP_ATOMIC);
+	if (ret)
+		pr_err("%s(%d) ERR: %d\n", __func__, __LINE__, ret);
+}
+
 static void bot_err_compl(struct usb_ep *ep, struct usb_request *req)
 {
 	struct usbg_cmd *cmd = req->context;
 	struct f_uas *fu = cmd->fu;
-	struct bulk_cs_wrap *csw = &fu->bot_status.csw;
-	int ret;
 
 	if (req->status < 0)
 		pr_err("ERR %s(%d)\n", __func__, __LINE__);
@@ -60,16 +84,10 @@ static void bot_err_compl(struct usb_ep *ep, struct usb_request *req)
 		usb_ep_queue(ep, req, GFP_ATOMIC);
 		return ;
 	}
-
-	csw->Tag = cmd->bot_tag;
-	csw->Status = US_BULK_STAT_FAIL;
-	fu->bot_status.req->context = cmd;
-	ret = usb_ep_queue(fu->ep_in, fu->bot_status.req, GFP_KERNEL);
-	if (ret)
-		pr_err("%s(%d) ERR: %d\n", __func__, __LINE__, ret);
+	bot_enqueue_sense_code(fu, cmd);
 }
 
-void bot_send_bad_status(struct usbg_cmd *cmd)
+static void bot_send_bad_status(struct usbg_cmd *cmd)
 {
 	struct f_uas *fu = cmd->fu;
 	struct bulk_cs_wrap *csw = &fu->bot_status.csw;
@@ -99,16 +117,7 @@ void bot_send_bad_status(struct usbg_cmd *cmd)
 		req->buf = fu->cmd.buf;
 		usb_ep_queue(ep, req, GFP_KERNEL);
 	} else {
-		/*
-		 * No clue what I should do here: CSW with response code 1 and
-		 * 2 will not always change Window's optinion about trying the
-		 * command again. Some commands fail and it is okay, others it
-		 * retries for ever.
-		 */
-		csw->Status = US_BULK_STAT_FAIL;
-		csw->Tag = cmd->bot_tag;
-		fu->bot_status.req->context = cmd;
-		usb_ep_queue(fu->ep_in, fu->bot_status.req, GFP_KERNEL);
+		bot_enqueue_sense_code(fu, cmd);
 	}
 }
 
diff --git a/drivers/target/usb-gadget/fabric.c b/drivers/target/usb-gadget/fabric.c
index f5fface..0283711 100644
--- a/drivers/target/usb-gadget/fabric.c
+++ b/drivers/target/usb-gadget/fabric.c
@@ -287,24 +287,22 @@ static void bot_cmd_work(struct work_struct *work)
 	struct se_cmd *se_cmd;
 	struct tcm_usbg_nexus *tv_nexus;
 	struct usbg_tpg *tpg;
-	int ret;
 	int dir;
 
 	se_cmd = &cmd->se_cmd;
 	tpg = cmd->fu->tpg;
 	tv_nexus = tpg->tpg_nexus;
 	dir = get_cmd_dir(cmd->cmd_buf);
-	if (dir < 0)
-		goto err;
+	if (dir < 0) {
+		transport_send_check_condition_and_sense(&cmd->se_cmd,
+				TCM_UNSUPPORTED_SCSI_OPCODE, 1);
+		return;
+	}
 
-	ret = target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess,
+	target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess,
 			cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun,
 			cmd->data_len, cmd->prio_attr, dir, 0);
-	if (ret)
-		goto err;
 	return;
-err:
-	bot_send_bad_status(cmd);
 }
 
 int bot_submit_command(struct f_uas *fu,
diff --git a/drivers/target/usb-gadget/usbg.h b/drivers/target/usb-gadget/usbg.h
index e1ad85f..97c6936 100644
--- a/drivers/target/usb-gadget/usbg.h
+++ b/drivers/target/usb-gadget/usbg.h
@@ -146,7 +146,6 @@ void usbg_detach(struct usbg_tpg *tpg);
 int usbg_submit_command(struct f_uas *fu, void *cmdbuf, unsigned int len);
 int bot_submit_command(struct f_uas *fu, void *cmdbuf, unsigned int len);
 void usbg_cmd_release(struct kref *ref);
-void bot_send_bad_status(struct usbg_cmd *cmd);
 void usbg_data_write_cmpl(struct usb_ep *ep, struct usb_request *req);
 int usbg_prepare_w_request(struct usbg_cmd *cmd, struct usb_request *req);
 
-- 
1.7.8.3

--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux