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 <oneukum@xxxxxxxx> --- 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html