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:
A bitstuff error happened during the transfer.
No response packet was received in time by the hardware.
-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.
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:
A bitstuff error happened during the transfer.
No response packet was received in time by the hardware.
-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.
Комментариев нет:
Отправить комментарий
Примечание. Отправлять комментарии могут только участники этого блога.