If the transfer is cancelled due to a disconnect or driver tear down (error code -ESHUTDOWN), then just free the command. However, if it got cancelled due to other reasons, then send a sense CHECK CONDITION status with TCM_CHECK_CONDITION_ABORT_CMD status to host notifying the delivery failure. Note that this is separate from TASK MANAGEMENT function abort task command, which will require a separate response IU. See UAS-r04 section 8. Signed-off-by: Thinh Nguyen <Thinh.Nguyen@xxxxxxxxxxxx> --- Changes in v2: - New patch drivers/usb/gadget/function/f_tcm.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index a10e74290664..116be1c47ac9 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -949,11 +949,16 @@ static void usbg_data_write_cmpl(struct usb_ep *ep, struct usb_request *req) { struct usbg_cmd *cmd = req->context; struct se_cmd *se_cmd = &cmd->se_cmd; + struct uas_stream *stream = uasp_get_stream_by_tag(cmd->fu, cmd->tag); cmd->state = UASP_QUEUE_COMMAND; - if (req->status == -ESHUTDOWN) - goto cleanup; + if (req->status == -ESHUTDOWN) { + stream->cmd = NULL; + target_put_sess_cmd(se_cmd); + transport_generic_free_cmd(&cmd->se_cmd, 0); + return; + } if (req->status) { pr_err("%s() state %d transfer failed\n", __func__, cmd->state); @@ -972,7 +977,8 @@ static void usbg_data_write_cmpl(struct usb_ep *ep, struct usb_request *req) cleanup: target_put_sess_cmd(se_cmd); - transport_generic_free_cmd(&cmd->se_cmd, 0); + transport_send_check_condition_and_sense(se_cmd, + TCM_CHECK_CONDITION_ABORT_CMD, 0); } static int usbg_prepare_w_request(struct usbg_cmd *cmd, struct usb_request *req) -- 2.28.0