Hi Greg,
here is a patch that adds three URB setup helpers that will allocate the
transfer buffer using kmalloc() and set the new URB_FREE_BUFFER flage to
make it free together with the URB. Please apply.
Regards
Marcel
USB: Introduce usb_setup_{control,bulk,int}_urb helpers
This patch adds usb_setup_{control,bulk,int}_urb helpers that will
allocate the transfer buffer and set URB_FREE_BUFFER flag for freeing
it when the reference count of an URB goes down to zero. This allows
an easy and simple construction of one-shot URBs.
Signed-off-by: Marcel Holtmann <[EMAIL PROTECTED]>
---
commit 2a3deb451a56722f4943f03e1a2b44a85f3b8db5
tree 21ce3f7992f969dfeb8ee8c9c9adce1c5d9d35d7
parent 189548642c5962e60c3667bdb3a703fe0bed12a6
author Marcel Holtmann <[EMAIL PROTECTED]> Tue, 26 Jun 2007 03:02:33 +0200
committer Marcel Holtmann <[EMAIL PROTECTED]> Tue, 26 Jun 2007 03:02:33 +0200
drivers/usb/core/urb.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/usb.h | 15 +++++++
2 files changed, 121 insertions(+), 0 deletions(-)
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 94ea972..fc00e49 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -478,6 +478,109 @@ void usb_kill_urb(struct urb *urb)
spin_unlock_irq(&urb->lock);
}
+/**
+ * usb_setup_control_urb - macro to help initializes a control urb
+ * @urb: pointer to the urb to initialize.
+ * @dev: pointer to the struct usb_device for this urb.
+ * @pipe: the endpoint pipe
+ * @setup_packet: pointer to the setup_packet buffer
+ * @size: requested buffer size
+ * @mem_flags: affect whether allocation may block
+ * @complete_fn: pointer to the usb_complete_t function
+ * @context: what to set the urb context to.
+ *
+ * Initializes a control urb with the proper information needed to submit
+ * it to a device and allocate transfer buffer for it.
+ */
+int usb_setup_control_urb(struct urb *urb, struct usb_device *dev,
+ unsigned int pipe,
+ unsigned char *setup_packet,
+ size_t size, gfp_t mem_flags,
+ usb_complete_t complete_fn, void *context)
+{
+ void *buffer;
+
+ buffer = kmalloc(size, mem_flags);
+ if (!buffer)
+ return -ENOMEM;
+
+ usb_fill_control_urb(urb, dev, pipe, setup_packet,
+ buffer, size, complete_fn, context);
+
+ urb->transfer_flags |= URB_FREE_BUFFER;
+
+ return 0;
+}
+
+/**
+ * usb_setup_bulk_urb - macro to help initialize a bulk urb
+ * @urb: pointer to the urb to initialize.
+ * @dev: pointer to the struct usb_device for this urb.
+ * @pipe: the endpoint pipe
+ * @size: requested buffer size
+ * @mem_flags: affect whether allocation may block
+ * @complete_fn: pointer to the usb_complete_t function
+ * @context: what to set the urb context to.
+ *
+ * Initializes a bulk urb with the proper information needed to submit it
+ * to a device and allocate transfer buffer for it.
+ */
+int usb_setup_bulk_urb(struct urb *urb, struct usb_device *dev,
+ unsigned int pipe,
+ size_t size, gfp_t mem_flags,
+ usb_complete_t complete_fn, void *context)
+{
+ void *buffer;
+
+ buffer = kmalloc(size, mem_flags);
+ if (!buffer)
+ return -ENOMEM;
+
+ usb_fill_bulk_urb(urb, dev, pipe, buffer, size, complete_fn, context);
+
+ urb->transfer_flags |= URB_FREE_BUFFER;
+
+ return 0;
+}
+
+/**
+ * usb_setup_int_urb - macro to help initialize a interrupt urb
+ * @urb: pointer to the urb to initialize.
+ * @dev: pointer to the struct usb_device for this urb.
+ * @pipe: the endpoint pipe
+ * @size: requested buffer size
+ * @mem_flags: affect whether allocation may block
+ * @complete_fn: pointer to the usb_complete_t function
+ * @context: what to set the urb context to.
+ * @interval: what to set the urb interval to, encoded like
+ * the endpoint descriptor's bInterval value.
+ *
+ * Initializes a interrupt urb with the proper information needed to submit
+ * it to a device and allocate transfer buffer for it.
+ * Note that high speed interrupt endpoints use a logarithmic encoding of
+ * the endpoint interval, and express polling intervals in microframes
+ * (eight per millisecond) rather than in frames (one per millisecond).
+ */
+int usb_setup_int_urb(struct urb *urb, struct usb_device *dev,
+ unsigned int pipe,
+ size_t size, gfp_t mem_flags,
+ usb_complete_t complete_fn, void *context,
+ int interval)
+{
+ void *buffer;
+
+ buffer = kmalloc(size, mem_flags);
+ if (!buffer)
+ return -ENOMEM;
+
+ usb_fill_int_urb(urb, dev, pipe, buffer, size,
+ complete_fn, context, interval);
+
+ urb->transfer_flags |= URB_FREE_BUFFER;
+
+ return 0;
+}
+
EXPORT_SYMBOL(usb_init_urb);
EXPORT_SYMBOL(usb_alloc_urb);
EXPORT_SYMBOL(usb_free_urb);
@@ -485,4 +588,7 @@ EXPORT_SYMBOL(usb_get_urb);
EXPORT_SYMBOL(usb_submit_urb);
EXPORT_SYMBOL(usb_unlink_urb);
EXPORT_SYMBOL(usb_kill_urb);
+EXPORT_SYMBOL(usb_setup_control_urb);
+EXPORT_SYMBOL(usb_setup_bulk_urb);
+EXPORT_SYMBOL(usb_setup_int_urb);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 94bd38a..ee75560 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1271,6 +1271,21 @@ 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);
+int usb_setup_control_urb(struct urb *urb, struct usb_device *dev,
+ unsigned int pipe,
+ unsigned char *setup_packet,
+ size_t size, gfp_t mem_flags,
+ usb_complete_t complete_fn, void *context);
+int usb_setup_bulk_urb(struct urb *urb, struct usb_device *dev,
+ unsigned int pipe,
+ size_t size, gfp_t mem_flags,
+ usb_complete_t complete_fn, void *context);
+int usb_setup_int_urb(struct urb *urb, struct usb_device *dev,
+ unsigned int pipe,
+ size_t size, gfp_t mem_flags,
+ usb_complete_t complete_fn, void *context,
+ int interval);
+
void *usb_buffer_alloc (struct usb_device *dev, size_t size,
gfp_t mem_flags, dma_addr_t *dma);
void usb_buffer_free (struct usb_device *dev, size_t size,
-------------------------------------------------------------------------
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