[PATCH] USB: Update Documentation/usb/URB.txt
This patch (as564) updates Documentation/usb/URB.txt, bringing it roughly up to the current level. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
c6c88834b2
commit
0fc084eaff
|
@ -1,5 +1,6 @@
|
||||||
Revised: 2000-Dec-05.
|
Revised: 2000-Dec-05.
|
||||||
Again: 2002-Jul-06
|
Again: 2002-Jul-06
|
||||||
|
Again: 2005-Sep-19
|
||||||
|
|
||||||
NOTE:
|
NOTE:
|
||||||
|
|
||||||
|
@ -18,8 +19,8 @@ called USB Request Block, or URB for short.
|
||||||
and deliver the data and status back.
|
and deliver the data and status back.
|
||||||
|
|
||||||
- Execution of an URB is inherently an asynchronous operation, i.e. the
|
- Execution of an URB is inherently an asynchronous operation, i.e. the
|
||||||
usb_submit_urb(urb) call returns immediately after it has successfully queued
|
usb_submit_urb(urb) call returns immediately after it has successfully
|
||||||
the requested action.
|
queued the requested action.
|
||||||
|
|
||||||
- Transfers for one URB can be canceled with usb_unlink_urb(urb) at any time.
|
- Transfers for one URB can be canceled with usb_unlink_urb(urb) at any time.
|
||||||
|
|
||||||
|
@ -94,8 +95,9 @@ To free an URB, use
|
||||||
|
|
||||||
void usb_free_urb(struct urb *urb)
|
void usb_free_urb(struct urb *urb)
|
||||||
|
|
||||||
You may not free an urb that you've submitted, but which hasn't yet been
|
You may free an urb that you've submitted, but which hasn't yet been
|
||||||
returned to you in a completion callback.
|
returned to you in a completion callback. It will automatically be
|
||||||
|
deallocated when it is no longer in use.
|
||||||
|
|
||||||
|
|
||||||
1.4. What has to be filled in?
|
1.4. What has to be filled in?
|
||||||
|
@ -145,30 +147,36 @@ to get seamless ISO streaming.
|
||||||
|
|
||||||
1.6. How to cancel an already running URB?
|
1.6. How to cancel an already running URB?
|
||||||
|
|
||||||
For an URB which you've submitted, but which hasn't been returned to
|
There are two ways to cancel an URB you've submitted but which hasn't
|
||||||
your driver by the host controller, call
|
been returned to your driver yet. For an asynchronous cancel, call
|
||||||
|
|
||||||
int usb_unlink_urb(struct urb *urb)
|
int usb_unlink_urb(struct urb *urb)
|
||||||
|
|
||||||
It removes the urb from the internal list and frees all allocated
|
It removes the urb from the internal list and frees all allocated
|
||||||
HW descriptors. The status is changed to reflect unlinking. After
|
HW descriptors. The status is changed to reflect unlinking. Note
|
||||||
usb_unlink_urb() returns with that status code, you can free the URB
|
that the URB will not normally have finished when usb_unlink_urb()
|
||||||
with usb_free_urb().
|
returns; you must still wait for the completion handler to be called.
|
||||||
|
|
||||||
There is also an asynchronous unlink mode. To use this, set the
|
To cancel an URB synchronously, call
|
||||||
the URB_ASYNC_UNLINK flag in urb->transfer flags before calling
|
|
||||||
usb_unlink_urb(). When using async unlinking, the URB will not
|
void usb_kill_urb(struct urb *urb)
|
||||||
normally be unlinked when usb_unlink_urb() returns. Instead, wait
|
|
||||||
for the completion handler to be called.
|
It does everything usb_unlink_urb does, and in addition it waits
|
||||||
|
until after the URB has been returned and the completion handler
|
||||||
|
has finished. It also marks the URB as temporarily unusable, so
|
||||||
|
that if the completion handler or anyone else tries to resubmit it
|
||||||
|
they will get a -EPERM error. Thus you can be sure that when
|
||||||
|
usb_kill_urb() returns, the URB is totally idle.
|
||||||
|
|
||||||
|
|
||||||
1.7. What about the completion handler?
|
1.7. What about the completion handler?
|
||||||
|
|
||||||
The handler is of the following type:
|
The handler is of the following type:
|
||||||
|
|
||||||
typedef void (*usb_complete_t)(struct urb *);
|
typedef void (*usb_complete_t)(struct urb *, struct pt_regs *)
|
||||||
|
|
||||||
i.e. it gets just the URB that caused the completion call.
|
I.e., it gets the URB that caused the completion call, plus the
|
||||||
|
register values at the time of the corresponding interrupt (if any).
|
||||||
In the completion handler, you should have a look at urb->status to
|
In the completion handler, you should have a look at urb->status to
|
||||||
detect any USB errors. Since the context parameter is included in the URB,
|
detect any USB errors. Since the context parameter is included in the URB,
|
||||||
you can pass information to the completion handler.
|
you can pass information to the completion handler.
|
||||||
|
@ -176,17 +184,11 @@ you can pass information to the completion handler.
|
||||||
Note that even when an error (or unlink) is reported, data may have been
|
Note that even when an error (or unlink) is reported, data may have been
|
||||||
transferred. That's because USB transfers are packetized; it might take
|
transferred. That's because USB transfers are packetized; it might take
|
||||||
sixteen packets to transfer your 1KByte buffer, and ten of them might
|
sixteen packets to transfer your 1KByte buffer, and ten of them might
|
||||||
have transferred succesfully before the completion is called.
|
have transferred succesfully before the completion was called.
|
||||||
|
|
||||||
|
|
||||||
NOTE: ***** WARNING *****
|
NOTE: ***** WARNING *****
|
||||||
Don't use urb->dev field in your completion handler; it's cleared
|
NEVER SLEEP IN A COMPLETION HANDLER. These are normally called
|
||||||
as part of giving urbs back to drivers. (Addressing an issue with
|
|
||||||
ownership of periodic URBs, which was otherwise ambiguous.) Instead,
|
|
||||||
use urb->context to hold all the data your driver needs.
|
|
||||||
|
|
||||||
NOTE: ***** WARNING *****
|
|
||||||
Also, NEVER SLEEP IN A COMPLETION HANDLER. These are normally called
|
|
||||||
during hardware interrupt processing. If you can, defer substantial
|
during hardware interrupt processing. If you can, defer substantial
|
||||||
work to a tasklet (bottom half) to keep system latencies low. You'll
|
work to a tasklet (bottom half) to keep system latencies low. You'll
|
||||||
probably need to use spinlocks to protect data structures you manipulate
|
probably need to use spinlocks to protect data structures you manipulate
|
||||||
|
@ -229,24 +231,10 @@ ISO data with some other event stream.
|
||||||
Interrupt transfers, like isochronous transfers, are periodic, and happen
|
Interrupt transfers, like isochronous transfers, are periodic, and happen
|
||||||
in intervals that are powers of two (1, 2, 4 etc) units. Units are frames
|
in intervals that are powers of two (1, 2, 4 etc) units. Units are frames
|
||||||
for full and low speed devices, and microframes for high speed ones.
|
for full and low speed devices, and microframes for high speed ones.
|
||||||
|
|
||||||
Currently, after you submit one interrupt URB, that urb is owned by the
|
|
||||||
host controller driver until you cancel it with usb_unlink_urb(). You
|
|
||||||
may unlink interrupt urbs in their completion handlers, if you need to.
|
|
||||||
|
|
||||||
After a transfer completion is called, the URB is automagically resubmitted.
|
|
||||||
THIS BEHAVIOR IS EXPECTED TO BE REMOVED!!
|
|
||||||
|
|
||||||
Interrupt transfers may only send (or receive) the "maxpacket" value for
|
|
||||||
the given interrupt endpoint; if you need more data, you will need to
|
|
||||||
copy that data out of (or into) another buffer. Similarly, you can't
|
|
||||||
queue interrupt transfers.
|
|
||||||
THESE RESTRICTIONS ARE EXPECTED TO BE REMOVED!!
|
|
||||||
|
|
||||||
Note that this automagic resubmission model does make it awkward to use
|
|
||||||
interrupt OUT transfers. The portable solution involves unlinking those
|
|
||||||
OUT urbs after the data is transferred, and perhaps submitting a final
|
|
||||||
URB for a short packet.
|
|
||||||
|
|
||||||
The usb_submit_urb() call modifies urb->interval to the implemented interval
|
The usb_submit_urb() call modifies urb->interval to the implemented interval
|
||||||
value that is less than or equal to the requested interval value.
|
value that is less than or equal to the requested interval value.
|
||||||
|
|
||||||
|
In Linux 2.6, unlike earlier versions, interrupt URBs are not automagically
|
||||||
|
restarted when they complete. They end when the completion handler is
|
||||||
|
called, just like other URBs. If you want an interrupt URB to be restarted,
|
||||||
|
your completion handler must resubmit it.
|
||||||
|
|
Loading…
Reference in New Issue