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

Previous thread: lists of medical professionals in america by representative Freeman on Monday, June 25, 2007 - 5:42 pm. (1 message)

Next thread: hs_eth_function and fs_eth_function seem unused in ether.c by rparker on Monday, June 25, 2007 - 7:05 pm. (1 message)
From: Marcel Holtmann
Date: Monday, June 25, 2007 - 6:07 pm

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

From: Marcel Holtmann
Date: Monday, June 25, 2007 - 6:14 pm

while I was creating this patch, I was thinking about its usefulness. It
will make the drivers more simpler, but still every driver that is gonna
use it has to allocate the URB itself. So why not go one step ahead and
create usb_alloc_{control,bulk,int}_urb helpers that will allocate the
URB, its transfer buffer set the appropriate flags.

Comments?

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/
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel


From: Pete Zaitcev
Date: Monday, June 25, 2007 - 9:50 pm

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?

BTW, you sure like empty lines...

-- Pete

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


From: Alan Stern
Date: Tuesday, June 26, 2007 - 7:30 am

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.)

Alan Stern


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


From: Marcel Holtmann
Date: Thursday, June 28, 2007 - 8:40 am

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

From: Alan Stern
Date: Thursday, June 28, 2007 - 7:21 pm

In general this looks fine.  The awkward pipe constructor is okay
because this routine encapsulates it.  And with any luck it will go
away completely, in time.

You should remove the comment about incrementing the reference count.  
It's confusing since the code doesn't do a get, and anyway people will
naturally expect the refcount to start at 1.

Oh yes -- you should _add_ a comment line about the URB_FREE_BUFFER
flag.  Mention that when the driver calls usb_free_urb(), the transfer
buffer will automatically be freed at the same time.

It's hard to judge how useful it would be without seeing examples of
the code that would use it.  Presumably you have some real code all set
to go.

Alan Stern


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


From: David Brownell
Date: Sunday, July 1, 2007 - 7:08 pm

Seeing all these recent discussions reminds me that the USB gadget
stack (peripheral side, not host side) has drivers using a similar
idiom.  Have a look at drivers/usb/gadget/zero.c and see the two
routines alloc_ep_req() and free_ep_req() ...

In those cases, nothing like a URB_FREE_BUFFER flag was needed.
And I confess I think a purely layered/wrappered approach seems
best to me here; the core doesn't _need_ such a mechanism, ergo
it shouldn't have one.  It's easy enough to audit code to make
sure that if they use one routine to allocate, they use its
sibling to free.

Plus, I think I'd rather see the usb_host_endpoint be passed around
instead of the usb_endpoint_desriptor it holds.  That's just one
level less indirection, but the host_endpoint struct is a more
appropriate focus for the core and HCDs since it can hold various
other stuff that's useful.

- Dave


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


From: Greg KH
Date: Monday, June 25, 2007 - 10:19 pm

You mean something like the following, but also for bulk and int?  I
like it, it reduces the number of allocations and frees we have to do as
the transfer buffer will get freed automatically with the urb, when it
is.

What do people think?

thanks,

greg k-h


--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -578,6 +578,41 @@ int usb_wait_anchor_empty_timeout(struct
 }
 EXPORT_SYMBOL_GPL(usb_wait_anchor_empty_timeout);
 
+/**
+ * usb_alloc_control_urb - function to create and initialize a control urb
+ * @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 and the transfer buffer for the urb, with the
+ * proper information needed to submit it to a device.  A pointer to the urb
+ * will be returned.  If there is an error creating the urb, NULL will be
+ * returned.
+ */
+struct urb *usb_alloc_control_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)
+{
+	struct urb *urb;
+	void *buffer;
+
+	urb = kzalloc(sizeof(*urb) + size, mem_flags);
+	if (!urb)
+		return NULL;
+	buffer = ((unsigned char *)(urb) + size);
+
+	usb_fill_control_urb(urb, dev, pipe, setup_packet,
+			     buffer, size, complete_fn, context);
+
+	return urb;
+}
+EXPORT_SYMBOL(usb_alloc_control_urb);
+
 EXPORT_SYMBOL(usb_init_urb);
 EXPORT_SYMBOL(usb_alloc_urb);
 EXPORT_SYMBOL(usb_free_urb);
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1334,6 +1334,11 @@ extern void usb_unanchor_urb(struct urb 
 extern int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor,
 					 unsigned int timeout);
 
+struct urb *usb_alloc_control_urb(struct ...
From: Alan Stern
Date: Tuesday, June 26, 2007 - 7:32 am

This is no good.  The buffer has to be located in its own cache line; 
it can't be combined with another data structure like the URB.  They 
must be allocated separately.

Alan Stern


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


From: Greg KH
Date: Tuesday, June 26, 2007 - 8:34 am

Why?  I thought the only requirement be that they are from DMA-able
memory.

thanks,

greg k-h

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


From: Alan Stern
Date: Tuesday, June 26, 2007 - 9:46 am

Another important requirement of streaming DMA-IN transfers is that the
CPU must not touch the buffer's cache line while it is mapped for DMA.  
If it does, you risk reading stale values into the CPU's cache.  Then 
when the device puts the correct values in the buffer, the CPU ignores 
them (and maybe even overwrites them!) because it thinks it already 
knows the buffer's contents.

Now if you knew for certain that the buffer would only be used for OUT 
transfers then you might be okay.  But I'm not certain, and in any case 
it's best to obey the access rules for DMA.

Alan Stern


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


From: David Brownell
Date: Sunday, July 1, 2007 - 7:27 pm

That's the primary criterion, yes ... I don't think that snippet of
code above is entirely wrong.  It would be best to round up the size
of the URB part, so any buffer part always starts on a new cacheline.

What I like about that is that it hits the heap only once, not twice.

Almost true... the constraint applies to either DMA_DIRECTION_* value,
and dma_sync_single_for_cpu()/dma_sync_single_for_device() are standard
ways to loosen the constraint.

The buffer is mapped for DMA at some point in the URB submit sequence,
and I'm fairly sure that both usbcore and the HCD expect to access the
other parts of the URB after that point.  So ensuring that there's no

Cacheline sharing is something to be wary of.  It's exactly the reason
why DMA to/from stack resident buffers is dangerous.  I ran into a bug
in the MMC stack a while ago, caused by its (current) use of stack DMA.
(Maybe I should submit a patch for RC7, hmm.)

The sharing is rarely an issue on x86, because of cache snooping.  But
on your average embedded CPU, which would rather not spend silicon
(or at most, spend it on integrating some useful peripheral controller),
there is no cache snooping.  So those cache smashing problems DO show
up without all that much effort.

- Dave


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


From: Alan Stern
Date: Monday, July 2, 2007 - 7:42 am

Yes, that's a good approach.  It could work for Iso URBs as well, since 
we can calculate the number of packet descriptors from the total 
transfer size and the endpoint maxpacket size (assuming each Iso packet 

Yes, with the dma_sync routines you can reduce the window during which 
the cache line must be undisturbed.

However I don't understand the necessity for this with DMA-OUT 
transfers.  Obviously _writing_ to the buffer during the transfer is 
dangerous, but it's not apparent why _reading_ the buffer should be 
bad.

Alan Stern


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


From: David Brownell
Date: Friday, July 6, 2007 - 5:11 pm

There could be performance impacts on some systems.  And you
said "access" originally, not "write" or "read"... "access"
allows writing (which is troublesome), but "read" wouldn't.

- Dave


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


Previous thread: lists of medical professionals in america by representative Freeman on Monday, June 25, 2007 - 5:42 pm. (1 message)

Next thread: hs_eth_function and fs_eth_function seem unused in ether.c by rparker on Monday, June 25, 2007 - 7:05 pm. (1 message)