13.3. USB Urbs
The USB code in the Linux kernel
communicates with all USB devices using something called a
urb (USB request block). This
request block is described with the struct urb
structure and can be found in the include/linux/usb.h
file.
A urb is used to send or receive data to or from a specific USB
endpoint on a specific USB device in an asynchronous manner. It is
used much like a kiocb structure is used in the
filesystem async I/O code or as a struct
skbuff is used in the networking code. A USB
device driver may allocate many urbs for a single endpoint or may
reuse a single urb for many different endpoints, depending on the
need of the driver. Every endpoint in a device can handle a queue of
urbs, so that multiple urbs can be sent to the same endpoint before
the queue is empty. The typical
lifecycle
of a urb is as follows:
Created by a USB device driver. Assigned to a specific endpoint of a specific USB device. Submitted to the USB core, by the USB device driver. Submitted to the specific USB host controller driver for the
specified device by the USB core. Processed by the USB host controller driver that makes a USB transfer
to the device. When the urb is completed, the USB host controller driver notifies
the USB device driver.
Urbs can also be canceled any time by the driver that submitted the
urb, or by the USB core if the device is removed from the system.
urbs are dynamically created and contain an internal reference count
that enables them to be automatically freed when the last user of the
urb releases it.
The procedure described in this chapter for handling urbs is useful,
because it permits streaming and other complex, overlapping
communications that allow drivers to achieve the highest possible
data transfer speeds. But less cumbersome procedures are available if
you just want to send individual bulk or control messages and do not
care about data throughput rates. (See the Section 13.5.)
13.3.1. struct urb
The fields of the
struct urb
structure that matter to a USB device driver are:
- struct usb_device *dev
-
Pointer to the struct usb_device to which this urb
is sent. This variable must be initialized by the USB driver before
the urb can be sent to the USB core.
- unsigned int pipe
-
Endpoint information for the specific struct
usb_device that this urb is to be sent to. This
variable must be initialized by the USB driver before the urb can be
sent to the USB core.
To set fields of this structure, the driver uses the following
functions as appropriate, depending on the direction of traffic. Note
that every endpoint can be of only one type.
- unsigned int usb_sndctrlpipe(struct usb_device *dev, unsigned int
- endpoint)
-
Specifies a control OUT endpoint for the specified USB device with
the specified endpoint number.
- unsigned int usb_rcvctrlpipe(struct usb_device *dev, unsigned int
- endpoint)
-
Specifies a control IN endpoint for the specified USB device with the
specified endpoint number.
- unsigned int usb_sndbulkpipe(struct usb_device *dev, unsigned int
- endpoint)
-
Specifies a bulk OUT endpoint for the specified USB device with the
specified endpoint number.
- unsigned int usb_rcvbulkpipe(struct usb_device *dev, unsigned int
- endpoint)
-
Specifies a bulk IN endpoint for the specified USB device with the
specified endpoint number.
- unsigned int usb_sndintpipe(struct usb_device *dev, unsigned int endpoint)
-
Specifies an interrupt OUT endpoint for the specified USB device with
the specified endpoint number.
- unsigned int usb_rcvintpipe(struct usb_device *dev, unsigned int endpoint)
-
Specifies an interrupt IN endpoint for the specified USB device with
the specified endpoint number.
- unsigned int usb_sndisocpipe(struct usb_device *dev, unsigned int
- endpoint)
-
Specifies an isochronous OUT endpoint for the specified USB device
with the specified endpoint number.
- unsigned int usb_rcvisocpipe(struct usb_device *dev, unsigned int
- endpoint)
-
Specifies an isochronous IN endpoint for the specified USB device
with the specified endpoint number.
- unsigned int transfer_flags
-
This variable can be set to a number of different bit values,
depending on what the USB driver wants to happen to the urb. The
available values are:
- URB_SHORT_NOT_OK
-
When set, it specifies that any short read on an IN endpoint that
might occur should be treated as an error by the USB core. This value
is useful only for urbs that are to be read from the USB device, not
for write urbs.
- URB_ISO_ASAP
-
If the urb is isochronous, this bit can be set if the driver wants
the urb to be scheduled, as soon as the bandwidth utilization allows
it to be, and to set the start_frame variable in
the urb at that point. If this bit is not set for an isochronous urb,
the driver must specify the start_frame value and
must be able to recover properly if the transfer cannot start at that
moment. See the upcoming section about isochronous urbs for more
information.
- URB_NO_TRANSFER_DMA_MAP
-
Should be set when the urb contains a DMA buffer to be transferred.
The USB core uses the buffer pointed to by the
TRansfer_dma variable and not the buffer pointed
to by the transfer_buffer variable.
- URB_NO_SETUP_DMA_MAP
-
Like the URB_NO_TRANSFER_DMA_MAP bit, this bit is
used for control urbs that have a DMA buffer already set up. If it is
set, the USB core uses the buffer pointed to by the
setup_dma variable instead of the
setup_packet variable.
- URB_ASYNC_UNLINK
-
If set, the call to usb_unlink_urb for this urb
returns almost immediately, and the urb is unlinked in the
background. Otherwise, the function waits until the urb is completely
unlinked and finished before returning. Use this bit with care,
because it can make synchronization issues very difficult to debug.
- URB_NO_FSBR
-
Used by only the UHCI USB Host controller driver and tells it to not
try to do Front Side Bus Reclamation logic. This bit should generally
not be set, because machines with a UHCI host controller create a lot
of CPU overhead, and the PCI bus is saturated waiting on a urb that
sets this bit.
- URB_ZERO_PACKET
-
If set, a bulk out urb finishes by sending a short packet containing
no data when the data is aligned to an endpoint packet boundary. This
is needed by some broken USB devices (such as a number of USB to IR
devices) in order to work properly.
- URB_NO_INTERRUPT
-
If set, the hardware may not generate an interrupt when the urb is
finished. This bit should be used with care and only when queuing
multiple urbs to the same endpoint. The USB core functions use this
in order to do DMA buffer transfers.
- void *transfer_buffer
-
Pointer to the buffer to be used when sending data to the device (for
an OUT urb) or when receiving data from the device (for an IN urb).
In order for the host controller to properly access this buffer, it
must be created with a call to kmalloc, not on the
stack or statically. For control endpoints, this buffer is for the
data stage of the transfer.
- dma_addr_t transfer_dma
-
Buffer to be used to transfer data to the USB device using DMA.
- int transfer_buffer_length
-
The length of the buffer pointed to by the
transfer_buffer or the
transfer_dma variable (as only one can be used for
a urb). If this is 0, neither transfer buffers are
used by the USB core.
For an OUT endpoint, if the endpoint maximum size is smaller than the
value specified in this variable, the transfer to the USB device is
broken up into smaller chunks in order to properly transfer the data.
This large transfer occurs in consecutive USB frames. It is much
faster to submit a large block of data in one urb, and have the USB
host controller split it up into smaller pieces, than it is to send
smaller buffers in consecutive order.
- unsigned char *setup_packet
-
Pointer to the setup packet for a control urb. It is transferred
before the data in the transfer buffer. This variable is valid only
for control urbs.
- dma_addr_t setup_dma
-
DMA buffer for the setup packet for a control urb. It is transferred
before the data in the normal transfer buffer. This variable is valid
only for control urbs.
- usb_complete_t complete
-
Pointer to the completion handler function that is called by the USB
core when the urb is completely transferred or when an error occurs
to the urb. Within this function, the USB driver may inspect the urb,
free it, or resubmit it for another transfer. (See the Section 13.3.4 for more details
about the completion handler.)
The usb_complete_t typedef is defined as:
typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
- void *context
-
Pointer to a data blob that can be set by the USB driver. It can be
used in the completion handler when the urb is returned to the
driver. See the following section for more details about this
variable.
- int actual_length
-
When the urb is finished, this variable is set to the actual length
of the data either sent by the urb (for OUT urbs) or received by the
urb (for IN urbs.) For IN urbs, this must be used instead of the
transfer_buffer_length variable, because the data
received could be smaller than the whole buffer size.
- int status
-
When the urb is finished, or being processed by the USB core, this
variable is set to the current status of the urb. The only time a USB
driver can safely access this variable is in the urb completion
handler function (described in Section 13.3.4). This
restriction is to prevent race conditions that occur while the urb is
being processed by the USB core. For isochronous urbs, a successful
value (0) in this variable merely indicates
whether the urb has been unlinked. To obtain a detailed status on
isochronous urbs, the iso_frame_desc variables
should be checked.
Valid values for this variable include:
- 0
-
The urb transfer was successful.
- -ENOENT
-
The urb was stopped by a call to usb_kill_urb.
- -ECONNRESET
-
The urb was unlinked by a call to
usb_unlink_urb, and the
TRansfer_flags variable of the urb was set to
URB_ASYNC_UNLINK.
- -EINPROGRESS
-
The urb is still being processed by the USB host controllers. If your
driver ever sees this value, it is a bug in your driver.
- -EPROTO
-
One of the following errors occurred with this urb:
- -EILSEQ
-
There was a CRC mismatch in the urb transfer.
- -EPIPE
-
The endpoint is now stalled. If the endpoint involved is not a
control endpoint, this error can be cleared through a call to the
function usb_clear_halt.
- -ECOMM
-
Data was received faster during the transfer than it could be written
to system memory. This error value happens only for an IN urb.
- -ENOSR
-
Data could not be retrieved from the system memory during the
transfer fast enough to keep up with the requested USB data rate.
This error value happens only for an OUT urb.
- -EOVERFLOW
-
A "babble" error happened to the
urb. A "babble" error occurs when
the endpoint receives more data than the endpoint's
specified maximum packet size.
- -EREMOTEIO
-
Occurs only if the URB_SHORT_NOT_OK flag is set in
the urb's transfer_flags variable
and means that the full amount of data requested by the urb was not
received.
- -ENODEV
-
The USB device is now gone from the system.
- -EXDEV
-
Occurs only for a isochronous urb and means that the transfer was
only partially completed. In order to determine what was transferred,
the driver must look at the individual frame status.
- -EINVAL
-
Something very bad happened with the urb. The USB kernel
documentation describes what this value means:
ISO madness, if this happens: Log off and go home
It also can happen if a parameter is incorrectly set in the urb
stucture or if an incorrect function parameter in the
usb_submit_urb call submitted the urb to the USB
core.
- -ESHUTDOWN
-
There was a severe error with the USB host controller driver; it has
now been disabled, or the device was disconnected from the system,
and the urb was submitted after the device was removed. It can also
occur if the configuration was changed for the device, while the urb
was submitted to the device.
Generally, the error values -EPROTO,
-EILSEQ, and -EOVERFLOW
indicate hardware problems with the device, the device firmware, or
the cable connecting the device to the computer.
- int start_frame
-
Sets or returns the initial frame number for isochronous transfers to
use.
- int interval
-
The interval at which the urb is polled. This is valid only for
interrupt or isochronous urbs. The value's units
differ depending on the speed of the device. For low-speed and
full-speed devices, the units are frames, which are equivalent to
milliseconds. For devices, the units are in microframes, which is
equivalent to units of 1/8 milliseconds. This value must be set by
the USB driver for isochronous or interrupt urbs before the urb is
sent to the USB core.
- int number_of_packets
-
Valid only for isochronous urbs and specifies the number of
isochronous transfer buffers to be handled by this urb. This value
must be set by the USB driver for isochronous urbs before the urb is
sent to the USB core.
- int error_count
-
Set by the USB core only for isochronous urbs after their completion.
It specifies the number of isochronous transfers that reported any
type of error.
- struct usb_iso_packet_descriptor iso_frame_desc[0]
-
Valid only for isochronous urbs. This variable is an array of the
struct usb_iso_packet_descriptor structures that
make up this urb. This structure allows a single urb to define a
number of isochronous transfers at once. It is also used to collect
the transfer status of each individual transfer.
The struct usb_iso_packet_descriptor is made up of
the following fields:
- unsigned int offset
-
The offset into the transfer buffer (starting at 0
for the first byte) where this packet's data is
located.
- unsigned int length
-
The length of the transfer buffer for this packet.
- unsigned int actual_length
-
The length of the data received into the transfer buffer for this
isochronous packet.
- unsigned int status
-
The status of the individual isochronous transfer of this packet. It
can take the same return values as the main struct
urb structure's status
variable.
13.3.2. Creating and Destroying Urbs
The struct urb structure must
never
be created statically in a driver or
within another structure, because that would break the reference
counting scheme used by the USB core for urbs. It must be created
with a call to the
usb_alloc_urb function. This function has the
prototype:
struct urb *usb_alloc_urb(int iso_packets, int mem_flags);
The first parameter, iso_packets, is the number of
isochronous packets this urb should contain. If you do not want to
create an isochronous urb, this variable should be set to
0. The second parameter,
mem_flags, is the same type of flag that is passed
to the kmalloc function call to allocate memory
from the kernel (see Section 8.1.1
for the details on these
flags). If the function is successful in allocating enough space for
the urb, a pointer to the urb is returned to the caller. If the
return value is NULL, some error occurred within
the USB core, and the driver needs to clean up properly.
After a urb has been created, it must be properly initialized before
it can be used by the USB core. See the next sections for how to
initialize different types of urbs.
In order to tell the USB core that the driver is finished with the
urb, the driver must call the usb_free_urb
function. This function only has one argument:
void usb_free_urb(struct urb *urb);
The argument is a pointer to the struct urb you
want to release. After this function is called, the urb structure is
gone, and the driver cannot access it any more.
13.3.2.1 Interrupt urbs
The function
usb_fill_int_urb
is a helper
function
to properly initialize a urb to be sent to a interrupt endpoint of a
USB device:
void usb_fill_int_urb(struct urb *urb, struct usb_device *dev,
unsigned int pipe, void *transfer_buffer,
int buffer_length, usb_complete_t complete,
void *context, int interval);
This function contains a lot of parameters:
- struct urb *urb
-
A pointer to the urb to be initialized.
- struct usb_device *dev
-
The USB device to which this urb is to be sent.
- unsigned int pipe
-
The specific endpoint of the USB device to which this urb is to be
sent. This value is created with the previously mentioned
usb_sndintpipe or
usb_rcvintpipe functions.
- void *transfer_buffer
-
A pointer to the buffer from which outgoing data is taken or into
which incoming data is received. Note that this can not be a static
buffer and must be created with a call to
kmalloc.
- int buffer_length
-
The length of the buffer pointed to by the
transfer_buffer pointer.
- usb_complete_t complete
-
Pointer to the completion handler that is called when this urb is
completed.
- void *context
-
Pointer to the blob that is added to the urb structure for later
retrieval by the completion handler function.
- int interval
-
The interval at which that this urb should be scheduled. See the
previous description of the struct urb structure
to find the proper units for this value.
13.3.2.2 Bulk urbs
Bulk urbs are initialized much like interrupt urbs. The function
that does this is
usb_fill_bulk_urb, and it looks like:
void usb_fill_bulk_urb(struct urb *urb, struct usb_device *dev,
unsigned int pipe, void *transfer_buffer,
int buffer_length, usb_complete_t complete,
void *context);
The function parameters are all the same as in the
usb_fill_int_urb function. However, there is no
interval parameter because bulk urbs have no
interval value. Please note that the unsigned
int pipe variable must be
initialized with a call to the usb_sndbulkpipe
or usb_rcvbulkpipe function.
The usb_fill_int_urb function does not set the
transfer_flags variable in the urb, so any
modification to this field has to be done by the driver itself.
13.3.2.3 Control urbs
Control urbs are initialized almost the same way as
bulk urbs, with a call to the function
usb_fill_control_urb:
void usb_fill_control_urb(struct urb *urb, struct usb_device *dev,
unsigned int pipe, unsigned char *setup_packet,
void *transfer_buffer, int buffer_length,
usb_complete_t complete, void *context);
The function parameters are all the same as in the
usb_fill_bulk_urb function, except that there is
a new parameter, unsigned char
*setup_packet, which must point to the setup
packet data that is to be sent to the endpoint. Also, the
unsigned int pipe variable must
be initialized with a call to the
usb_sndctrlpipe or
usb_rcvictrlpipe function.
The usb_fill_control_urb function does not set
the TRansfer_flags variable in the urb, so any
modification to this field has to be done by the driver itself. Most
drivers do not use this function, as it is much simpler to use the
synchronous API calls as described in Section 13.5.
13.3.2.4 Isochronous urbs
Isochronous urbs unfortunately do not have
an initializer function like the interrupt, control, and bulk urbs
do. So they must be initialized "by
hand" in the driver before they can be submitted to
the USB core. The following is an example of how to properly
initialize this type of urb. It was taken from the
konicawc.c kernel driver located in the
drivers/usb/media directory in the main kernel
source tree.
urb->dev = dev;
urb->context = uvd;
urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp-1);
urb->interval = 1;
urb->transfer_flags = URB_ISO_ASAP;
urb->transfer_buffer = cam->sts_buf[i];
urb->complete = konicawc_isoc_irq;
urb->number_of_packets = FRAMES_PER_DESC;
urb->transfer_buffer_length = FRAMES_PER_DESC;
for (j=0; j < FRAMES_PER_DESC; j++) {
urb->iso_frame_desc[j].offset = j;
urb->iso_frame_desc[j].length = 1;
}
13.3.3. Submitting Urbs
Once the urb has been
properly
created and initialized by the USB driver, it is ready to be
submitted to the USB core to be sent out to the USB device. This is
done with a call to the function
usb_submit_urb:
int usb_submit_urb(struct urb *urb, int mem_flags);
The urb parameter is a pointer to the urb that is
to be sent to the device. The mem_flags parameter
is equivalent to the same parameter that is passed to the
kmalloc call and is used to tell the USB core
how to allocate any memory buffers at this moment in time.
After a urb has been submitted to the USB core successfully, it
should never try to access any fields of the urb structure until the
complete function is called.
Because the function usb_submit_urb can be
called at any time (including from within an interrupt context), the
specification of the mem_flags variable must be
correct. There are really only three valid values that should be
used, depending on when usb_submit_urb is being
called:
- GFP_ATOMIC
-
This value should be used whenever the following are true:
The caller is within a urb completion handler, an interrupt, a bottom
half, a tasklet, or a timer callback. The caller is holding a spinlock or rwlock. Note that if a semaphore
is being held, this value is not necessary. The current->state is not
TASK_RUNNING. The state is always
TASK_RUNNING unless the driver has changed the
current state itself.
- GFP_NOIO
-
This value should be used if the driver is in the block I/O patch. It
should also be used in the error handling path of all storage-type
devices.
- GFP_KERNEL
-
This should be used for all other situations that do not fall into
one of the previously mentioned categories.
13.3.4. Completing Urbs: The Completion Callback Handler
If the call to usb_submit_urb
was
successful, transferring control of the urb to the USB core, the
function returns 0; otherwise, a negative error
number is returned. If the function succeeds, the completion handler
of the urb (as specified by the complete
function pointer) is called exactly once when the urb is completed.
When this function is called, the USB core is finished with the URB,
and control of it is now returned to the device driver.
There are only three ways a urb can be finished and have the
complete
function called:
The urb is successfully sent to the device, and the device returns
the proper acknowledgment. For an OUT urb, the data was successfully
sent, and for an IN urb, the requested data was successfully
received. If this has happened, the status
variable in the urb is set to 0. Some kind of error happened when sending or receiving data from the
device. This is noted by the error value in the
status variable in the urb structure. The urb was "unlinked" from the USB
core. This happens either when the driver tells the USB core to
cancel a submitted urb with a call to
usb_unlink_urb or
usb_kill_urb, or when a device is removed from
the system and a urb had been submitted to it.
An example of how to test for the different return values within a
urb completion call is shown later in this chapter.
13.3.5. Canceling Urbs
To stop a urb that has been
submitted to the USB core, the functions
usb_kill_urb
or
usb_unlink_urb should be called:
int usb_kill_urb(struct urb *urb);
int usb_unlink_urb(struct urb *urb);
The urb parameter for both of these functions is a
pointer to the urb that is to be canceled.
When the function is usb_kill_urb, the urb
lifecycle is stopped. This function is usually used when the device
is disconnected from the system, in the disconnect callback.
For some drivers, the usb_unlink_urb function
should be used to tell the USB core to stop an urb. This function
does not wait for the urb to be fully stopped before returning to the
caller. This is useful for stopping the urb while in an interrupt
handler or when a spinlock is held, as waiting for a urb to fully
stop requires the ability for the USB core to put the calling process
to sleep. This function requires that the
URB_ASYNC_UNLINK flag value be set in the urb
that is being asked to be stopped in order to work properly.
|