summaryrefslogtreecommitdiffstats
path: root/Documentation/usb/URB.txt
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/usb/URB.txt')
-rw-r--r--Documentation/usb/URB.txt61
1 files changed, 33 insertions, 28 deletions
diff --git a/Documentation/usb/URB.txt b/Documentation/usb/URB.txt
index 7d99567ad..234c75cf3 100644
--- a/Documentation/usb/URB.txt
+++ b/Documentation/usb/URB.txt
@@ -1,3 +1,5 @@
+Revised: 2000-Dec-05.
+
1. Specification of the API
1.1. Basic concept or 'What is an URB?'
@@ -8,16 +10,16 @@ called USB Request Block, or URB for short.
- An URB consists of all relevant information to execute any USB transaction
and deliver the data and status back.
-- Execution of an URB is an inherently asynchronous operation, i.e. the
-submit_urb(urb) call returns immediately after it has successfully queued
+- Execution of an URB is inherently an asynchronous operation, i.e. the
+usb_submit_urb(urb) call returns immediately after it has successfully queued
the requested action.
- Ongoing transfers for one URB (e.g. ISO) can simply be canceled with
-unlink_urb(urb) at any time.
+usb_unlink_urb(urb) at any time.
- Each URB has a completion handler, which is called after the action
has been successfully completed or canceled (INT transfers behave a bit
-different, see below). The URB also contains a context-pointer for free
+differently, see below). The URB also contains a context-pointer for free
usage and information passing to the completion handler.
- URBs can be linked. After completing one URB, the next one can be
@@ -31,6 +33,8 @@ URB-machinery.
typedef struct urb
{
+ spinlock_t lock; // lock for the URB
+
// ignore, for host controller/URB machine internal use
void *hcpriv; // private data for host controller
struct list_head urb_list; // list pointer to all active urbs
@@ -39,12 +43,12 @@ typedef struct urb
struct urb* next; // pointer to next URB
struct usb_device *dev; // pointer to associated USB device
-// pipe is assembled by the various well known pipe-macros in usb.h
+// pipe is assembled by the various well-known pipe macros in usb.h
unsigned int pipe; // pipe information
// status after each completion
int status; // returned status
- unsigned int transfer_flags; // ASAP, SP_OK, etc.
+ unsigned int transfer_flags; // ASAP, DISABLE_SPD, etc.
// for data stage (CTRL), BULK, INT and ISO
void *transfer_buffer; // associated data buffer
@@ -55,7 +59,7 @@ typedef struct urb
// setup stage for CTRL (always 8 bytes!)
unsigned char* setup_packet; // setup packet (control only)
-
+
// with ASAP, start_frame is set to the determined frame
int start_frame; // start frame (iso/irq)
int number_of_packets; // # of packets (iso/int)
@@ -66,7 +70,7 @@ typedef struct urb
usb_complete_t complete; // pointer to completion routine
//
// specification of the requested data offsets and length for ISO
- iso_packet_descriptor_t iso_frame_desc[0];
+ iso_packet_descriptor_t iso_frame_desc[0];
} urb_t, *purb_t;
@@ -74,7 +78,7 @@ typedef struct urb
URBs are allocated with the following call
- purb_t alloc_urb(int isoframes)
+ purb_t usb_alloc_urb(int isoframes)
Return value is a pointer to the allocated URB, 0 if allocation failed.
The parameter isoframes specifies the number of isochronous transfer frames
@@ -82,7 +86,7 @@ you want to schedule. For CTRL/BULK/INT, use 0.
To free an URB, use
- void free_urb(purb_t purb)
+ void usb_free_urb(purb_t purb)
This call also may free internal (host controller specific) memory in the
future.
@@ -91,12 +95,13 @@ future.
1.4. What has to be filled in?
Depending on the type of transaction, there are some macros
-(FILL_CONTROL_URB, FILL_BULK_URB, and FILL_INT_URB, defined in uhci.h)
+(FILL_CONTROL_URB, FILL_CONTROL_URB_TO, FILL_BULK_URB,
+FILL_BULK_URB_TO, and FILL_INT_URB, defined in usb.h)
that simplify the URB creation. In general, all macros need the usb
-device pointer, the pipe (usual format), the transfer buffer, the
-desired transfer length, the completion handler, and its context.
-Take a look at the uhci_control_msg-function that convert the old API
-into an URB.
+device pointer, the pipe (usual format from usb.h), the transfer buffer,
+the desired transfer length, the completion handler, and its context.
+Take a look at the usb_control_msg function that converts the old API
+into the URB API.
Flags:
For ISO there are two startup behaviors: Specified start_frame or ASAP.
@@ -114,7 +119,7 @@ re-submission for INT transfers that are being continued.
Just call
- int submit_urb(purb_t purb)
+ int usb_submit_urb(purb_t purb)
It immediately returns, either with status 0 (request queued) or some
error code, usually caused by the following:
@@ -128,7 +133,7 @@ error code, usually caused by the following:
- Invalid INT interval (-EINVAL)
- More than one packet for INT (-EINVAL)
-After submission, urb->status is USB_ST_URB_PENDING.
+After submission, urb->status is USB_ST_URB_PENDING (-EINPROGRESS).
For isochronous endpoints, subsequent submitting of URBs to the same endpoint
with the ASAP flag result in a seamless ISO streaming. Exception: The
@@ -142,18 +147,18 @@ independent of the transfer flags (implicitly ASAP).
For an URB which you've submitted, but which hasn't been returned to
your driver by the host controller, call
- int unlink_urb(purb_t purb)
+ int usb_unlink_urb(purb_t purb)
It removes the urb from the internal list and frees all allocated
HW descriptors. The status is changed to USB_ST_URB_KILLED. After
-unlink_urb() returns, you can safely free the URB with free_urb(urb)
+usb_unlink_urb() returns, you can safely free the URB with usb_free_urb(urb)
and all other possibly associated data (urb->context etc.)
There is also an asynchronous unlink mode. To use this, set the
the USB_ASYNC_UNLINK flag in urb->transfer flags before calling
usb_unlink_urb(). When using async unlinking, the URB will not
-normally be unlinked when unlink_urb() returns. Instead, wait for
-the completion handler to be called.
+normally be unlinked when usb_unlink_urb() returns. Instead, wait
+for the completion handler to be called.
1.7. What about the completion handler?
@@ -187,13 +192,13 @@ in completion handlers.
1.8. How to do isochronous (ISO) transfers?
For ISO transfers you have to append the iso_packet_descriptor_t structure
-to the URB for each frame you want to schedule. When using alloc_urb(n)
-(recommended), the isoframe-parameter n can be used to allocate the
-structures for n frames.
+to the URB for each frame you want to schedule. When using usb_alloc_urb(n)
+(recommended), the iso_packets parameter can be used to allocate the
+structures for iso_packets frames.
For each entry you have to specify the data offset for this frame (base is
transfer_buffer), and the length you want to write/expect to read.
-After completion, actual_length contains the actual transfered length and
+After completion, actual_length contains the actual transferred length and
status contains the resulting USB-status for the ISO transfer for this frame.
It is allowed to specify a varying length from frame to frame (e.g. for
audio synchronisation/adaptive transfer rates). You can also use the length
@@ -217,7 +222,7 @@ for 1, 2, 4,... 128ms. Only one URB is allocated for each interrupt. After
calling the completion handler, that URB is recycled by the host controller
driver (HCD).
With the submission of one URB, the interrupt is scheduled until it is
-canceled by unlink_urb.
-
-The submit_urb()-call modifies urb->interval to the rounded value.
+canceled by usb_unlink_urb.
+The usb_submit_urb() call modifies urb->interval to the implemented interval
+value that is less than or equal to the requested interval value.