diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2012-06-19 03:54:53 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-06-25 14:51:00 -0400 |
commit | bdd000fb34202530e5cd11260d06f57e2daf63c9 (patch) | |
tree | dd3ae6228d956f11929a0e3128b36f8bd658c80d | |
parent | 8aac863e9295c42683b5b39ab65e17711e21b34c (diff) |
uas: track urbs, kill inflight urbs on disconnect.
Use separate anchors for data and sense urbs, which
I think will be useful when implementing error handling.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/storage/uas.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index d8b7bc6ea141..875829a56183 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c | |||
@@ -41,6 +41,8 @@ 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 sense_urbs; | ||
45 | struct usb_anchor data_urbs; | ||
44 | int qdepth; | 46 | int qdepth; |
45 | unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe; | 47 | unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe; |
46 | unsigned use_streams:1; | 48 | unsigned use_streams:1; |
@@ -396,6 +398,7 @@ static int uas_submit_sense_urb(struct Scsi_Host *shost, | |||
396 | usb_free_urb(urb); | 398 | usb_free_urb(urb); |
397 | return SCSI_MLQUEUE_DEVICE_BUSY; | 399 | return SCSI_MLQUEUE_DEVICE_BUSY; |
398 | } | 400 | } |
401 | usb_anchor_urb(urb, &devinfo->sense_urbs); | ||
399 | return 0; | 402 | return 0; |
400 | } | 403 | } |
401 | 404 | ||
@@ -431,6 +434,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, | |||
431 | } | 434 | } |
432 | cmdinfo->state &= ~SUBMIT_DATA_IN_URB; | 435 | cmdinfo->state &= ~SUBMIT_DATA_IN_URB; |
433 | cmdinfo->state |= DATA_IN_URB_INFLIGHT; | 436 | cmdinfo->state |= DATA_IN_URB_INFLIGHT; |
437 | usb_anchor_urb(cmdinfo->data_in_urb, &devinfo->data_urbs); | ||
434 | } | 438 | } |
435 | 439 | ||
436 | if (cmdinfo->state & ALLOC_DATA_OUT_URB) { | 440 | if (cmdinfo->state & ALLOC_DATA_OUT_URB) { |
@@ -450,6 +454,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, | |||
450 | } | 454 | } |
451 | cmdinfo->state &= ~SUBMIT_DATA_OUT_URB; | 455 | cmdinfo->state &= ~SUBMIT_DATA_OUT_URB; |
452 | cmdinfo->state |= DATA_OUT_URB_INFLIGHT; | 456 | cmdinfo->state |= DATA_OUT_URB_INFLIGHT; |
457 | usb_anchor_urb(cmdinfo->data_out_urb, &devinfo->data_urbs); | ||
453 | } | 458 | } |
454 | 459 | ||
455 | if (cmdinfo->state & ALLOC_CMD_URB) { | 460 | if (cmdinfo->state & ALLOC_CMD_URB) { |
@@ -761,6 +766,8 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
761 | 766 | ||
762 | devinfo->intf = intf; | 767 | devinfo->intf = intf; |
763 | devinfo->udev = udev; | 768 | devinfo->udev = udev; |
769 | init_usb_anchor(&devinfo->sense_urbs); | ||
770 | init_usb_anchor(&devinfo->data_urbs); | ||
764 | uas_configure_endpoints(devinfo); | 771 | uas_configure_endpoints(devinfo); |
765 | 772 | ||
766 | result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 2); | 773 | result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 2); |
@@ -804,6 +811,8 @@ static void uas_disconnect(struct usb_interface *intf) | |||
804 | struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; | 811 | struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; |
805 | 812 | ||
806 | scsi_remove_host(shost); | 813 | scsi_remove_host(shost); |
814 | usb_kill_anchored_urbs(&devinfo->sense_urbs); | ||
815 | usb_kill_anchored_urbs(&devinfo->data_urbs); | ||
807 | uas_free_streams(devinfo); | 816 | uas_free_streams(devinfo); |
808 | kfree(devinfo); | 817 | kfree(devinfo); |
809 | } | 818 | } |