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