Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eda76959 authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman
Browse files

USB: add extension of anchor API, usb_unlink_anchored_urbs



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: default avatarOliver Neukum <oneukum@suse.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 9424ea29
Loading
Loading
Loading
Loading
+24 −0
Original line number Original line Diff line number Diff line
@@ -589,6 +589,30 @@ void usb_kill_anchored_urbs(struct usb_anchor *anchor)
}
}
EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs);
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
 * usb_wait_anchor_empty_timeout - wait for an anchor to be unused
 * @anchor: the anchor you want to become unused
 * @anchor: the anchor you want to become unused
+1 −0
Original line number Original line Diff line number Diff line
@@ -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 int usb_unlink_urb(struct urb *urb);
extern void usb_kill_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_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_anchor_urb(struct urb *urb, struct usb_anchor *anchor);
extern void usb_unanchor_urb(struct urb *urb);
extern void usb_unanchor_urb(struct urb *urb);
extern int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor,
extern int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor,