struct urb {
struct list_head urb_list;
struct usb_device * dev;
unsigned int pipe;
int status;
unsigned int transfer_flags;
void * transfer_buffer;
dma_addr_t transfer_dma;
int transfer_buffer_length;
int actual_length;
unsigned char * setup_packet;
dma_addr_t setup_dma;
int start_frame;
int number_of_packets;
int interval;
int error_count;
void * context;
usb_complete_t complete;
struct usb_iso_packet_descriptor * iso_frame_desc;
};
This structure identifies USB transfer requests. URBs must be allocated by calling usb_alloc_urb and freed with a call to usb_free_urb. Initialization may be done using various usb_fill_*_urb functions. URBs are submitted using usb_submit_urb, and pending requests may be canceled using usb_unlink_urb.
Normally drivers provide I/O buffers allocated with kmalloc or otherwise taken from the general page pool. That is provided by transfer_buffer (control requests also use setup_packet), and host controller drivers perform a dma mapping (and unmapping) for each buffer transferred. Those mapping operations can be expensive on some platforms (perhaps using a dma bounce buffer or talking to an IOMMU), although they're cheap on commodity x86 and ppc hardware.
Alternatively, drivers may pass the URB_NO_xxx_DMA_MAP transfer flags, which tell the host controller driver that no such mapping is needed since the device driver is DMA-aware. For example, a device driver might allocate a DMA buffer with usb_buffer_alloc or call usb_buffer_map. When these transfer flags are provided, host controller drivers will attempt to use the dma addresses found in the transfer_dma and/or setup_dma fields rather than determining a dma address themselves. (Note that transfer_buffer and setup_packet must still be set because not all host controllers use DMA, nor do virtual root hubs).
All URBs submitted must initialize dev, pipe, transfer_flags (may be zero), complete, timeout (may be zero). The URB_ASYNC_UNLINK transfer flag affects later invocations of the usb_unlink_urb routine.
All URBs must also initialize transfer_buffer and transfer_buffer_length. They may provide the URB_SHORT_NOT_OK transfer flag, indicating that short reads are to be treated as errors; that flag is invalid for write requests.
Bulk URBs may use the URB_ZERO_PACKET transfer flag, indicating that bulk OUT transfers should always terminate with a short packet, even if it means adding an extra zero length packet.
Control URBs must provide a setup_packet. The setup_packet and transfer_buffer may each be mapped for DMA or not, independently of the other. The transfer_flags bits URB_NO_TRANSFER_DMA_MAP and URB_NO_SETUP_DMA_MAP indicate which buffers have already been mapped. URB_NO_SETUP_DMA_MAP is ignored for non-control URBs.
Interrupt UBS must provide an interval, saying how often (in milliseconds or, for highspeed devices, 125 microsecond units) to poll for transfers. After the URB has been submitted, the interval and start_frame fields reflect how the transfer was actually scheduled. The polling interval may be more frequent than requested. For example, some controllers have a maximum interval of 32 microseconds, while others support intervals of up to 1024 microseconds. Isochronous URBs also have transfer intervals. (Note that for isochronous endpoints, as well as high speed interrupt endpoints, the encoding of the transfer interval in the endpoint descriptor is logarithmic.)
Isochronous URBs normally use the URB_ISO_ASAP transfer flag, telling the host controller to schedule the transfer as soon as bandwidth utilization allows, and then set start_frame to reflect the actual frame selected during submission. Otherwise drivers must specify the start_frame and handle the case where the transfer can't begin then. However, drivers won't know how bandwidth is currently allocated, and while they can find the current frame using usb_get_current_frame_number () they can't know the range for that frame number. (Ranges for frame counter values are HC-specific, and can go from 256 to 65536 frames from ``now''.)
Isochronous URBs have a different data transfer model, in part because the quality of service is only ``best effort''. Callers provide specially allocated URBs, with number_of_packets worth of iso_frame_desc structures at the end. Each such packet is an individual ISO transfer. Isochronous URBs are normally queued, submitted by drivers to arrange that transfers are at least double buffered, and then explicitly resubmitted in completion handlers, so that data (such as audio or video) streams at as constant a rate as the host controller scheduler can support.
The completion callback is made in_interrupt, and one of the first things that a completion handler should do is check the status field. The status field is provided for all URBs. It is used to report unlinked URBs, and status for all non-ISO transfers. It should not be examined before the URB is returned to the completion handler.
The context field is normally used to link URBs back to the relevant driver or request state.
When completion callback is invoked for non-isochronous URBs, the actual_length field tells how many bytes were transferred.
ISO transfer status is reported in the status and actual_length fields of the iso_frame_desc array, and the number of errors is reported in error_count. Completion callbacks for ISO transfers will normally (re)submit URBs to ensure a constant transfer rate.
This documentation is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For more details see the file COPYING in the source distribution of Linux.
If you have comments on the formatting of this manpage, then please contact Michael Still (mikal@stillhq.com).
This documentation was generated with kernel version 2.5.74.