Hi,

> after the discussion with Oliver at the LinuxTag last week, I started to
> re-write the hci_usb driver to remove this ugly cruft around the URB
> management in the driver. The basic driver (without ISOC support) is
> working perfectly fine and thanks to the reference count of the URB and
> the new USB anchor extension it is a really small and simple driver now.
> 
> However the buffer management for URBs that get re-submitted all the
> time is really ugly. It can be done inside the driver, but I think the
> USB core should provide some helpers here.
> 
> The attached patch is an attempt to integrate the buffer into the URB
> and let the URB take care of freeing it when it is no longer needed.
> This might not be optimal for all drivers, but it helps to reduce a lot
> of code in many drivers. And of course the old method of allocating or
> providing an external buffer is still available.

an alternate way would be to extend the usb_kill_anchored_urbs() with
its own complete handler that gets called for every anchored URB. This
would make it possible to cleanup the allocated buffers. I attached a
patch for that, too.

Regards

Marcel

diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index e3e49d8..fda0dd5 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -535,12 +535,13 @@ void usb_kill_urb(struct urb *urb)
 /**
  * usb_kill_anchored_urbs - cancel transfer requests en masse
  * @anchor: anchor the requests are bound to
+ * @complete: function called after urb has been killed
  *
  * this allows all outstanding URBs to be killed starting
  * from the back of the queue
  */
 
-void usb_kill_anchored_urbs(struct usb_anchor *anchor)
+void usb_kill_anchored_urbs(struct usb_anchor *anchor, usb_complete_t complete)
 {
 	struct urb *victim;
 
@@ -552,6 +553,8 @@ void usb_kill_anchored_urbs(struct usb_anchor *anchor)
 		spin_unlock_irq(&anchor->lock);
 		/* this will unanchor the URB */
 		usb_kill_urb(victim);
+		if (complete)
+			complete(victim);
 		usb_put_urb(victim);
 		spin_lock_irq(&anchor->lock);
 	}
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 60d9eef..2f3482b 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1287,7 +1287,7 @@ extern struct urb *usb_get_urb(struct urb *urb);
 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_kill_anchored_urbs(struct usb_anchor *anchor, usb_complete_t complete);
 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
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to