[PATCH] Add usb_setup_{control, bulk, int}_urb helpers

Marcel Holtmann <[email protected]>
Newsgroups gmane.linux.usb.devel
Message-ID <[email protected]>
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

-------------------------------------------------------------------------
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/

_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
patch-add-urb-setup-helpers (text/plain, 5.6 KB)
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,
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.