diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2012-09-25 04:47:04 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-09-25 18:32:23 -0400 |
commit | a0e39e346822d115b2446a7c0032d799c48ac1a5 (patch) | |
tree | 2b6c36977fe8be92dfadce4f7e3d1380022e3d22 /drivers/usb | |
parent | 5ed338778f917a035f0f0a52327fc4f72e36f7a1 (diff) |
USB: uas: keep track of command urbs
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/storage/uas.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 638cd64f9610..ab66365adb96 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c | |||
@@ -41,6 +41,7 @@ struct sense_iu_old { | |||
41 | struct uas_dev_info { | 41 | struct uas_dev_info { |
42 | struct usb_interface *intf; | 42 | struct usb_interface *intf; |
43 | struct usb_device *udev; | 43 | struct usb_device *udev; |
44 | struct usb_anchor cmd_urbs; | ||
44 | struct usb_anchor sense_urbs; | 45 | struct usb_anchor sense_urbs; |
45 | struct usb_anchor data_urbs; | 46 | struct usb_anchor data_urbs; |
46 | int qdepth, resetting; | 47 | int qdepth, resetting; |
@@ -431,6 +432,7 @@ static int uas_submit_task_urb(struct scsi_cmnd *cmnd, gfp_t gfp, | |||
431 | err = usb_submit_urb(urb, gfp); | 432 | err = usb_submit_urb(urb, gfp); |
432 | if (err) | 433 | if (err) |
433 | goto err; | 434 | goto err; |
435 | usb_anchor_urb(urb, &devinfo->cmd_urbs); | ||
434 | 436 | ||
435 | return 0; | 437 | return 0; |
436 | 438 | ||
@@ -521,18 +523,22 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, | |||
521 | 523 | ||
522 | if (cmdinfo->state & ALLOC_CMD_URB) { | 524 | if (cmdinfo->state & ALLOC_CMD_URB) { |
523 | cmdinfo->cmd_urb = uas_alloc_cmd_urb(devinfo, gfp, cmnd, | 525 | cmdinfo->cmd_urb = uas_alloc_cmd_urb(devinfo, gfp, cmnd, |
524 | cmdinfo->stream); | 526 | cmdinfo->stream); |
525 | if (!cmdinfo->cmd_urb) | 527 | if (!cmdinfo->cmd_urb) |
526 | return SCSI_MLQUEUE_DEVICE_BUSY; | 528 | return SCSI_MLQUEUE_DEVICE_BUSY; |
527 | cmdinfo->state &= ~ALLOC_CMD_URB; | 529 | cmdinfo->state &= ~ALLOC_CMD_URB; |
528 | } | 530 | } |
529 | 531 | ||
530 | if (cmdinfo->state & SUBMIT_CMD_URB) { | 532 | if (cmdinfo->state & SUBMIT_CMD_URB) { |
533 | usb_get_urb(cmdinfo->cmd_urb); | ||
531 | if (usb_submit_urb(cmdinfo->cmd_urb, gfp)) { | 534 | if (usb_submit_urb(cmdinfo->cmd_urb, gfp)) { |
532 | scmd_printk(KERN_INFO, cmnd, | 535 | scmd_printk(KERN_INFO, cmnd, |
533 | "cmd urb submission failure\n"); | 536 | "cmd urb submission failure\n"); |
534 | return SCSI_MLQUEUE_DEVICE_BUSY; | 537 | return SCSI_MLQUEUE_DEVICE_BUSY; |
535 | } | 538 | } |
539 | usb_anchor_urb(cmdinfo->cmd_urb, &devinfo->cmd_urbs); | ||
540 | usb_put_urb(cmdinfo->cmd_urb); | ||
541 | cmdinfo->cmd_urb = NULL; | ||
536 | cmdinfo->state &= ~SUBMIT_CMD_URB; | 542 | cmdinfo->state &= ~SUBMIT_CMD_URB; |
537 | cmdinfo->state |= COMMAND_INFLIGHT; | 543 | cmdinfo->state |= COMMAND_INFLIGHT; |
538 | } | 544 | } |
@@ -670,6 +676,7 @@ static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd) | |||
670 | int err; | 676 | int err; |
671 | 677 | ||
672 | devinfo->resetting = 1; | 678 | devinfo->resetting = 1; |
679 | usb_kill_anchored_urbs(&devinfo->cmd_urbs); | ||
673 | usb_kill_anchored_urbs(&devinfo->sense_urbs); | 680 | usb_kill_anchored_urbs(&devinfo->sense_urbs); |
674 | usb_kill_anchored_urbs(&devinfo->data_urbs); | 681 | usb_kill_anchored_urbs(&devinfo->data_urbs); |
675 | err = usb_reset_device(udev); | 682 | err = usb_reset_device(udev); |
@@ -868,6 +875,7 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
868 | devinfo->intf = intf; | 875 | devinfo->intf = intf; |
869 | devinfo->udev = udev; | 876 | devinfo->udev = udev; |
870 | devinfo->resetting = 0; | 877 | devinfo->resetting = 0; |
878 | init_usb_anchor(&devinfo->cmd_urbs); | ||
871 | init_usb_anchor(&devinfo->sense_urbs); | 879 | init_usb_anchor(&devinfo->sense_urbs); |
872 | init_usb_anchor(&devinfo->data_urbs); | 880 | init_usb_anchor(&devinfo->data_urbs); |
873 | uas_configure_endpoints(devinfo); | 881 | uas_configure_endpoints(devinfo); |
@@ -913,6 +921,7 @@ static void uas_disconnect(struct usb_interface *intf) | |||
913 | struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; | 921 | struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; |
914 | 922 | ||
915 | scsi_remove_host(shost); | 923 | scsi_remove_host(shost); |
924 | usb_kill_anchored_urbs(&devinfo->cmd_urbs); | ||
916 | usb_kill_anchored_urbs(&devinfo->sense_urbs); | 925 | usb_kill_anchored_urbs(&devinfo->sense_urbs); |
917 | usb_kill_anchored_urbs(&devinfo->data_urbs); | 926 | usb_kill_anchored_urbs(&devinfo->data_urbs); |
918 | uas_free_streams(devinfo); | 927 | uas_free_streams(devinfo); |