Use a TMF_ABORT_TASK TMF_IU in the abort handler,
to deal with commands we need to get rid of.

Signed-off-by: Oliver Neukum <oneu...@suse.com>
---
 drivers/usb/storage/uas.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index a8052ec..1b901c8 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -428,6 +428,10 @@ static void uas_cmd_cmplt(struct urb *urb)
        usb_free_urb(urb);
 }
 
+static void uas_tmf_cmplt(struct urb *urb)
+{
+}
+
 static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp,
                                      struct scsi_cmnd *cmnd,
                                      enum dma_data_direction dir)
@@ -715,9 +719,11 @@ static int uas_eh_abort_handler(struct scsi_cmnd *cmnd)
 {
        struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
        struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
+       struct task_mgmt_iu *tmf = devinfo->tmf_iu;
        struct urb *data_in_urb = NULL;
        struct urb *data_out_urb = NULL;
        unsigned long flags;
+       int err;
 
        spin_lock_irqsave(&devinfo->lock, flags);
 
@@ -726,6 +732,24 @@ static int uas_eh_abort_handler(struct scsi_cmnd *cmnd)
        /* Ensure that try_complete does not call scsi_done */
        cmdinfo->state |= COMMAND_ABORTED;
 
+       usb_fill_bulk_urb(devinfo->management_urb,
+                         devinfo->udev,
+                         devinfo->cmd_pipe, /* shared */
+                         devinfo->tmf_iu,
+                         sizeof(devinfo->tmf_iu),
+                         uas_tmf_cmplt,
+                         cmnd->device->host);
+       tmf->iu_id = IU_ID_TASK_MGMT;
+       tmf->tag = cpu_to_be16(1);
+       tmf->function = TMF_ABORT_TASK;
+       tmf->task_tag = cmdinfo->uas_tag; /* already BE */
+
+       err = usb_submit_urb(devinfo->management_urb, GFP_NOIO);
+       if (err < 0) /* unkillable */
+               goto give_up;
+
+give_up:
+
        /* Drop all refs to this cmnd, kill data urbs to break their ref */
        devinfo->cmnd[cmdinfo->uas_tag - TAG_OFFSET] = NULL;
        if (cmdinfo->state & DATA_IN_URB_INFLIGHT)
-- 
2.1.4

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

Reply via email to