Given the discussion on INTR-OUT transfers, I thought it'd be useful to write out my current thoughts on how we should resolve this ... since it involves driver API changes as well as changes to each of the host controller drivers.
Here's a quick writeup, including rationale and some sketches of API updates (for 2.5). Comments? - Dave GOAL: support INTR-OUT and INTR-IN transfers with one API model which could also be used for a device controller API using an URB-like model. CURRENT MODEL: all interrupt transfers are specified with using an URB with transfer_buffer_length set to a fixed packet size, and a fixed polling interval. Also, current host controller drivers say only one interrupt URB (usually of at most maxpacketsize) may be queued. One notable problem with that model relates to the fixed transfer buffer length. When writing data, the length may need to vary: different HID reports may have different sizes, as one example. The current model only allows sizes to vary for reading data, by enabling short packets. A related problem is that when data is not available, there's no way to say "don't write data during this period, but I may have some later." COMPARISON: most device hardware makes each transfer be individually enabled and sized. Interrupts on completion can be used to enable/size the next transfer. Some (like the EZ-USB FX2) have options such as single, double, triple, and even quad buffering (helps when doing highspeed transfers with slowish and/or busy CPUs). Such functionality is not available today for Linux-USB. API CHANGE #1: Let INTR completion handlers change the transfer_buffer_length. A value of "-1" (it's not a size_t!!) would mean "don't transfer anything". Any other value, up to the maximum allowed by the endpoint descriptor (which is what would control the bandwidth allocation by the HCD), would be legal. Today, this would mostly be used for INTR-OUT (or host-writes-to-device). For a device side API it would be used regularly on INTR-IN transfers (or device-writes-to-host). This could either be done (a) with a special API function, like usb_modify_transfer (struct urb *urb, int size) or (b) by just modifying the HCDs to use the current transfer_buffer_length when re-enabling the transfer after a completion callback finished. I'd prefer (a) since it lets "too big" be reported to drivers. Doing that cleanly would also mean adding a new core-to-HCD call, which I'd rather avoid ... though it would let unmodified HCDs cause error reports. (There are enough HCDs outside drivers/usb that I start to worry about seemingly "transparent" API changes.) It would also provide a clear way to re-enable transfers outside a completion handler, once transfer_buffer_length is set to "-1"; and it's a more direct analogue of how device hardware works. API CHANGE #2 (much less thought out): Support multi-buffering. Two options come to mind: 1) Let INTR transfers to a given endpoint be queued. At end of queue, the bandwidth is reclaimed. This is basically the same model as bulk transfers ... single buffered drivers might make completion handlers (re)submit the just-completed URB. HCDs wouldn't prune a QH/ED from the periodic schedule until nothing's queued (no TDs in their lists). And existing code for bulk queuing would be reused. 2) Use urb->next and insist that interrupt URBs be linked in rings, like ISO. Single buffered drivers would have urb->next == urb. Both of those seem like they'd be incompatible changes to the transfer model. All drivers would need to change, unless this were added as some kind of second interrupt transfer mode (yeech). API change #2 may get rid of any need for #1... Note that (1) gives a very simple answer for the question of "one shot" transfers, or ones like writing N bytes of data (N > maxpacket). Of those, I tend to prefer (1) although the model for bandwidth allocation needs to be looked at. For example, what about when urb->interval is not the same in the different URBs? (Error!) And what to do when the driver wants to keep its bandwidth allocation but not issue a transfer just now? I don't much like (2) because I've never liked the weak error reporting model inherent in the urb->next submission path. It also doesn't match the hardware's queuing model as well; all the HCs treat interrupt transfers pretty much like bulk ones that happen to live in the periodic schedule ... I'd rather see interrupt transfers look much more like bulk ones. _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel