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