Skip to content

Commit

Permalink
USB: add extension of anchor API, usb_unlink_anchored_urbs
Browse files Browse the repository at this point in the history
This adds the ability to trigger asynchronous unlinks of anchored URBs. This
is needed for error handling in the comntext of completion handlers, which
cannot sleep.

Signed-off-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Oliver Neukum authored and Greg Kroah-Hartman committed Apr 25, 2008
1 parent 9424ea2 commit eda7695
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 0 deletions.
24 changes: 24 additions & 0 deletions drivers/usb/core/urb.c
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,30 @@ void usb_kill_anchored_urbs(struct usb_anchor *anchor)
}
EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs);

/**
* usb_unlink_anchored_urbs - asynchronously cancel transfer requests en masse
* @anchor: anchor the requests are bound to
*
* this allows all outstanding URBs to be unlinked starting
* from the back of the queue. This function is asynchronous.
* The unlinking is just tiggered. It may happen after this
* function has returned.
*/
void usb_unlink_anchored_urbs(struct usb_anchor *anchor)
{
struct urb *victim;

spin_lock_irq(&anchor->lock);
while (!list_empty(&anchor->urb_list)) {
victim = list_entry(anchor->urb_list.prev, struct urb,
anchor_list);
/* this will unanchor the URB */
usb_unlink_urb(victim);
}
spin_unlock_irq(&anchor->lock);
}
EXPORT_SYMBOL_GPL(usb_unlink_anchored_urbs);

/**
* usb_wait_anchor_empty_timeout - wait for an anchor to be unused
* @anchor: the anchor you want to become unused
Expand Down
1 change: 1 addition & 0 deletions include/linux/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -1451,6 +1451,7 @@ extern int usb_submit_urb(struct urb *urb, gfp_t mem_flags);
extern int usb_unlink_urb(struct urb *urb);
extern void usb_kill_urb(struct urb *urb);
extern void usb_kill_anchored_urbs(struct usb_anchor *anchor);
extern void usb_unlink_anchored_urbs(struct usb_anchor *anchor);
extern void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor);
extern void usb_unanchor_urb(struct urb *urb);
extern int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor,
Expand Down

0 comments on commit eda7695

Please sign in to comment.