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

Marcel Holtmann <[email protected]>
Newsgroups gmane.linux.usb.devel
Message-ID <[email protected]>
Hi Alan,

> > Sounds even more useful. Better abandon the halfway wrappers for the new
> > ones. Another thing I'd think may be useful is to take the endpoint
> > address instead of the pipe, because the pipe type is known to each
> > wrapper, right?
> 
> I'm in favor of doing away with pipe values.  Bear in mind however that
> the endpoint address or usb_host_endpoint structure doesn't quite
> contain all the information of a pipe.  The extra missing ingredient is
> a way to specify the direction for Control transfers (with Bulk,
> Interrupt, or Isochronous transfers the endpoint descriptor determines
> the direction).
> 
> If you prefer, the direction can be or'ed into the high bit of the 
> endpoint number.  That's a reasonably standard approach, since it's how 
> endpoint descriptors are formatted.  (Note that devices do not contain 
> an endpoint descriptor for ep0.  usbcore makes up a fake descriptor of 
> its own, with the direction permanently set to OUT.)

the attached patch is an attempt for usb_alloc_bulk_urb() which will
allocate the URB itself and its transfer buffer. It also use the
endpoint data structure to create the pipe value. Please review it.

I can create the other helper functions if you think this would be
useful and is heading in the right direction.

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 (text/x-patch, 2.6 KB)
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 0601665..eb50664 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -482,6 +482,54 @@ void usb_kill_urb(struct urb *urb)
 	spin_unlock_irq(&urb->lock);
 }
 
+/**
+ * usb_alloc_bulk_urb - creates a new bulk urb for an USB driver to use
+ * @dev: pointer to the struct usb_device for this urb.
+ * @desc: pointer to the struct usb_endpoint_descriptor for this urb.
+ * @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.
+ *
+ * Creates a bulk urb for the USB driver to use, initializes a few internal
+ * structures, incrementes the usage counter, allocates the transfer buffer,
+ * sets the pipe information from the endpoint descriptor, and returns a
+ * pointer to it.
+ *
+ * If no memory is available, NULL is returned.
+ *
+ * The driver must call usb_free_urb() when it is finished with the urb.
+ */
+struct urb *usb_alloc_bulk_urb(struct usb_device *dev,
+				struct usb_endpoint_descriptor *desc,
+				size_t size, gfp_t mem_flags,
+				usb_complete_t complete_fn, void *context)
+{
+	unsigned int pipe;
+	struct urb *urb;
+	void *buffer;
+
+	urb = usb_alloc_urb(0, mem_flags);
+	if (!urb)
+		return NULL;
+
+	buffer = kmalloc(size, mem_flags);
+	if (!buffer) {
+		usb_free_urb(urb);
+		return NULL;
+	}
+
+	pipe = (PIPE_BULK << 30) |
+			__create_pipe(dev, desc->bEndpointAddress) |
+			(desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK);
+
+	usb_fill_bulk_urb(urb, dev, pipe, buffer, size, complete_fn, context);
+
+	urb->transfer_flags |= URB_FREE_BUFFER;
+
+	return urb;
+}
+
 EXPORT_SYMBOL(usb_init_urb);
 EXPORT_SYMBOL(usb_alloc_urb);
 EXPORT_SYMBOL(usb_free_urb);
@@ -489,4 +537,5 @@ EXPORT_SYMBOL(usb_get_urb);
 EXPORT_SYMBOL(usb_submit_urb);
 EXPORT_SYMBOL(usb_unlink_urb);
 EXPORT_SYMBOL(usb_kill_urb);
+EXPORT_SYMBOL(usb_alloc_bulk_urb);
 
diff --git a/include/linux/usb.h b/include/linux/usb.h
index e751593..1468e9c 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1271,6 +1271,10 @@ 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 struct urb *usb_alloc_bulk_urb(struct usb_device *dev,
+				struct usb_endpoint_descriptor *desc,
+				size_t size, gfp_t mem_flags,
+				usb_complete_t complete_fn, void *context);
 
 void *usb_buffer_alloc (struct usb_device *dev, size_t size,
 	gfp_t mem_flags, dma_addr_t *dma);
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.