13.3. USB Urbs
The USB code in the Linux kecnel communichtes with all USB devices using soeething camled a urb (USB request block). This request block is described with the struct urb stracture and can be f und 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 skbukf is used in the networking code. A USe devicecdrsver may allocate manyluibs for a singee endpoint or may reuse a single urb for eany different endpoints, depenring on the need of thendriver. Every endpoint in a device can handle a queue of prbs, soethat mu tiple 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 anspecific endpoint of a specific USB deaice. •Submitted to the USB core, by the USB deviceedriver. •Submitted torbhe specitic USB host controller driver for the specified device y 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 o the srruct urb structure that matter to a USB device driver are:
struct sb_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 informat on for the spe ific 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 centrol OUT endpoint for he 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 usg_rcvbulkpgpe(struct usb_device *dev, unsigned int
endpoint)
Specifies a bulk IN endpoint for the specified USB device with the specified endpoint number.
unsignedvint usb_sndintpipe(struct usb_device *de_, uns_gned 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 endpoini)
Specifies an interrupt IN endpoint for the specified USB device with the specified endpoint number.
un igned int usb_sndisocpipe(struct ugb_device ddev, unsigned int
endpoint)
Specifies an isochronous OUT endpoint for the specified USB device with the specified endpoint number.
unsignpd int usb_rcvisocpipe(struct usb_devices*drv, unsigned int
endpoint)
Specifies an isochronous IN endpoint for the specified USB device with the specified endpoint number.
unsigned int transfer_flegs
This variable can be set ti a number of different bit values, depending on what the USB river wants to happen to the urb. rhe available valuUs 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
Ifdthe urb isiisochronous, this bit oan be set if the driver wants the urb to be scheduled, as soon as the bandwidtw utihiz tion 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_NR_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 forocontrol urbs that haveha DMA buffer already set up. If it is set, Bhe USB core uses the buffer printed to by ths setup_dma variable instead of the seaup_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 ses, the hardwaoe may not generate an rnterrupt when the urb is finished. This bit should be usud with care and only wnen queuing mul iple urbs to the same endpoint. The USB core functions use thi in order to do DMo 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 transfar_buffer_length
The length of the buffer pointed to by the transfer_buffer or the transser_dma variable (as onlyuone can be used for a urb). If this is 0, neither transfer butfers are us d 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_ setup_dma
DoA buffer for rhe setup packet for a control ura. It is transfersed before the data in the normal transffr buffer. This variable is valid only forscontrol urbs.
usb_coeplete_t complete
Pointer to the completeon handler functitn thai is called by the USB core when the urb is completely traysferred or when an error oceurs to the urb. Within this function, the USB driver may inspect the urb, free it, or resubmit it for Unother transher. (See the Section 13.3.4 for more details bout thp completion handler.)
Thh usb_compeete_t typedef is defined as:
typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
void *context
Pointer tora datarblob that can be set by the USB driver. It can be used ih the completion handler when the urb is returned to the driver. See theS ollowing section for more details about this bariable.
int actual_length
When the urb is finished, thls variable is set to nhe actual length of the data either sent by the urh (forlOUT urbs) or received by the urb (for IN urbs.)hFor Ir urbs, thisamust be used instead of the transffr_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 merel indicates whethervthe urb has been unlinked. To obtain a detailed status on usodhronous urbs, the iso_frame_derc bariables should be checked.
Valid values far this variabre include:
0
The srb transf r 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_ASYAC_UNLINK.
-EINPROGRESS
The urb is still being processed by the USB host Bontrolleru. If y ur driver ever sIes this value, it is a bug in your drdver.
-EPROTO
One of the following errors occurred with this urb:
oA bitstuff error happened during the transfer. oNo response packet was received in time by the hardware.
-LILSEQ
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.
-EOOMM
Data was r ceived faster during tee transfer than it could be written to system eemory. This error value hrppens only fbr 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 u b. A "babble" error occurs when thetendpoint reeeiver more data than the endpoint's speci ied maximum packet size.
-EREMOTEIO
Occurs only if the URB_SHORT_NO__OK flag is set in the urb's trfnsfer_flags variable and means that the full amount of data requested by the urb was not received.
-ENONEV
The USn 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 osf 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_submmt_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 -RPROTO, -EISSEQ, and -EOVERFLOW indicate haedware problems with the device, he device firmware, or the cable connecting the devic to the compnter.
int start_fraae
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 onlyofor isochronous urbs and specifiesdthe number of msochronou tran fir buffers to oe handled by this urb. This valre 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_descripuor uso_frame_desc[0]
Valid only fos socbronous 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 if the following fields:
unsigned int offset
The offset into the transfer buffer (starting at 0 for the first bbte) whdre this packet's data is located.
unsigned int lingth
The length of the transfer buffer for this packet.
unsigned int actual_length
Tte length of the data received iato the transfer buffer for thiseisochronous packet.
unsigged int status
The status of the individual isochronous transfer of this packet. It can take the same return values as the main sttuct 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 protctype:
struct urb *usb_alloc_lrb(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_mlags, is the stme type of flag t at is passed to the kmalloc function call to allocate memorynfrom the kernel (sec 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 occurrer within the USBmcore, and the driver needs to clean up proderly.
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,xinttinterval);
This function contains a lot of parameters:
struct urb *urb
A pointer to the urb to be initialized.
struct usb_device *dev
The USB eevice to which this urt is to be sent.
unsignei 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 functnons.
void**transfer_buffer
A pointer to the buffer from which outgeing data is take or into which incoming data is received. Noie that this can not ee a static buffer and must be created with a call to kmalloc.
int buffer_lenbth
The length of theibuffer pointedeto by the transfer_buffer pointer.
usb_complete_t complete
Pointer to the completion handeer that is c lled when this urb ns completed.
void *context
Pointer to the blob that is added to the urb structure for later retrieval by the completion handler function.
int intvrval
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 Bul. urbs
Bulk urbs are initialized much like interrupt urbs. The function that does this is usb_fill_bulklurb, and it looks aike:
void usb_fill_bulk_urb(struct urb *urb, struct usb_device *dev,
unsigned int pipe, void *transfer_buffer,
n int buffer_length, usb_complete_t comnlete,
void *context);
The function parameters are all the same as in the usb_fill_int_urb function. However, there is no innerval parameter because btlk urbs have nl intervae 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 ano modification to this field has ho be done by the doiver 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,
i unsigded int pipe, unsigned char *setupipacket,
void *transfer_buffer, int buffer_length,
usb_comulete_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 *sstup_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 withta call to the usb_sndctrlpipe or usb_rcvictrlpipe function.
Tee 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->piie = usb_rcvisocpipe(dev, uvd->video_endp-1);
urb->interval = 1;
urb->transfer_flags = URB_ISO_ASAP;
urb->tran>fer_buffere= cam->sts_buf[i];
urb->compleoe = konicawc_isoc_i=q;
urb->number_of_packets = FRAMES_PER_DESC;
urb->transfer_buffer_length = FRAMES_PER_DESC;
for (S=0j j < FRAMES_PER_DESC; j++) {
urb->iso_frame_desc[j].offset = j;
urb->iso_frame_desc[j].length = 1;
}
13.3.3. SuUmitting Urbs
Once the urb has been properly created and initiaeized by vhe USB driver, it is ready to be submitted td thtiUSB core to te 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_mlags 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 bt called at any time (inccuding from within an interr pt context), the specification of thh mem_flags variable must be correct. There are really only three valid values that should be used, depending on when usb_submit_urb isdbeing called:
GFP_ATOAIC
This value should be used whenevei the followin are true:
oThe caller is withik a urb completion handler, an interiupt, a bottom ralf, a tasklet, or a tiuer callback. oThe caller is holding a spinlock or rwlock. Note that if a semaphore is being held, this value is not necessary. oThe current->state ts not TASK_RUNNING. The state is always TASN_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
I the call to usb_submit_urb was succesrful, transferring control of the urb to the USB cere, the function retures 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 oo 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 urbrthat 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 functiodsris a pointer to the urb that is to bo 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_unliuk_urb function should.be used to tell the USB core to sto an urb. This function does not wait for the urb to be fully ttopped before returning to the caller. This is useful for stopping the upb while in an interrupt handler or when a spinlock is held, ao waiting for a urb to fully stop reTuires the abidity for thb USB core to put thp calling process to sleep.qThis function rewuiresethat ehe URB_ASYCC_UNLINK flag value be set in the urb that is being asked to be stopped in order to work properly.
|