Poster of Linux kernelThe best gift for a Linux geek
 Linux kernel map 
⇦ prev ⇱ home next ⇨

13.5. USB Transfers Without Urbs

Sometimes a USB driver does not want to go through all of the hassle of creating a struct urb, initializing it, and then waiting for the urb completion function to run, just to send or receive some simple USB data. Two functions are available to provide a simpler interface.

13.5.1. usb_bulk_msg

usb_bulk_msg creates a USB bulk urb and sends it to the specified device, then waits for it to complete before returning to the caller. It is defined as:

int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
                 void *data, int len, int *actual_length,
                 int timeout);

The parameters of this function are:

struct usb_device *usb_dev

A pointer to the USB device to send the bulk message to.

unsigned int pipe

The specific endpoint of the USB device to which this bulk message is to be sent. This value is created with a call to either usb_sndbulkpipe or usb_rcvbulkpipe.

void *data

A pointer to the data to send to the device if this is an OUT endpoint. If this is an IN endpoint, this is a pointer to where the data should be placed after being read from the device.

int len

The length of the buffer that is pointed to by the data parameter.

int *actual_length

A pointer to where the function places the actual number of bytes that have either been transferred to the device or received from the device, depending on the direction of the endpoint.

int timeout

The amount of time, in jiffies, that should be waited before timing out. If this value is 0, the function waits forever for the message to complete.

If the function is successful, the return value is 0; otherwise, a negative error number is returned. This error number matches up with the error numbers previously described for urbs in Section 13.3.1. If successful, the actual_length parameter contains the number of bytes that were transferred or received from this message.

The following is an example of using this function call:

/* do a blocking bulk read to get data from the device */
retval = usb_bulk_msg(dev->udev,
              usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
              dev->bulk_in_buffer,
              min(dev->bulk_in_size, count),
              &count, HZ*10);

/* if the read was successful, copy the data to user space */
if (!retval) {
    if (copy_to_user(buffer, dev->bulk_in_buffer, count))
        retval = -EFAULT;
    else
        retval = count;
}

This example shows a simple bulk read from an IN endpoint. If the read is successful, the data is then copied to user space. This is typically done in a read function for a USB driver.

The usb_bulk_msg function cannot be called from within interrupt context or with a spinlock held. Also, this function cannot be canceled by any other function, so be careful when using it; make sure that your driver's disconnect knows enough to wait for the call to complete before allowing itself to be unloaded from memory.

13.5.2. usb_control_msg

The usb_control_msg function works just like the usb_bulk_msg function, except it allows a driver to send and receive USB control messages:

int usb_control_msg(struct usb_device *dev, unsigned int pipe,
                    _ _u8 request, _ _u8 requesttype,
                    _ _u16 value, _ _u16 index,
                    void *data, _ _u16 size, int timeout);

The parameters of this function are almost the same as usb_bulk_msg, with a few important differences:

struct usb_device *dev

A pointer to the USB device to send the control message to.

unsigned int pipe

The specific endpoint of the USB device that this control message is to be sent to. This value is created with a call to either usb_sndctrlpipe or usb_rcvctrlpipe.

_ _u8 request

The USB request value for the control message.

_ _u8 requesttype

The USB request type value for the control message

_ _u16 value

The USB message value for the control message.

_ _u16 index

The USB message index value for the control message.

void *data

A pointer to the data to send to the device if this is an OUT endpoint. If this is an IN endpoint, this is a pointer to where the data should be placed after being read from the device.

_ _u16 size

The size of the buffer that is pointed to by the data parameter.

int timeout

The amount of time, in jiffies, that should be waited before timing out. If this value is 0, the function will wait forever for the message to complete.

If the function is successful, it returns the number of bytes that were transferred to or from the device. If it is not successful, it returns a negative error number.

The parameters request, requesttype, value, and index all directly map to the USB specification for how a USB control message is defined. For more information on the valid values for these parameters and how they are used, see Chapter 9 of the USB specification.

Like the function usb_bulk_msg, the function usb_control_msg cannot be called from within interrupt context or with a spinlock held. Also, this function cannot be canceled by any other function, so be careful when using it; make sure that your driver disconnect function knows enough to wait for the call to complete before allowing itself to be unloaded from memory.

13.5.3. Other USB Data Functions

A number of helper functions in the USB core can be used to retrieve standard information from all USB devices. These functions cannot be called from within interrupt context or with a spinlock held.

The function usb_get_descriptor retrieves the specified USB descriptor from the specified device. The function is defined as:

int usb_get_descriptor(struct usb_device *dev, unsigned char type,
                       unsigned char index, void *buf, int size);

This function can be used by a USB driver to retrieve from the struct usb_device structure any of the device descriptors that are not already present in the existing struct usb_device and struct usb_interface structures, such as audio descriptors or other class specific information. The parameters of the function are:

struct usb_device *usb_dev

A pointer to the USB device that the descriptor should be retrieved from.

unsigned char type

The descriptor type. This type is described in the USB specification and can be one of the following types:

USB_DT_DEVICE
USB_DT_CONFIG
USB_DT_STRING
USB_DT_INTERFACE
USB_DT_ENDPOINT
USB_DT_DEVICE_QUALIFIER
USB_DT_OTHER_SPEED_CONFIG
USB_DT_INTERFACE_POWER
USB_DT_OTG
USB_DT_DEBUG
USB_DT_INTERFACE_ASSOCIATION
USB_DT_CS_DEVICE
USB_DT_CS_CONFIG
USB_DT_CS_STRING
USB_DT_CS_INTERFACE
USB_DT_CS_ENDPOINT

unsigned char index

The number of the descriptor that should be retrieved from the device.

void *buf

A pointer to the buffer to which you copy the descriptor.

int size

The size of the memory pointed to by the buf variable.

If this function is successful, it returns the number of bytes read from the device. Otherwise, it returns a negative error number returned by the underlying call to usb_control_msg that this function makes.

One of the more common uses for the usb_get_descriptor call is to retrieve a string from the USB device. Because this is quite common, there is a helper function for it called usb_get_string:

int usb_get_string(struct usb_device *dev, unsigned short langid,
                   unsigned char index, void *buf, int size);

If successful, this function returns the number of bytes received by the device for the string. Otherwise, it returns a negative error number returned by the underlying call to usb_control_msg that this function makes.

If this function is successful, it returns a string encoded in the UTF-16LE format (Unicode, 16 bits per character, in little-endian byte order) in the buffer pointed to by the buf parameter. As this format is usually not very useful, there is another function, called usb_string, that returns a string that is read from a USB device and is already converted into an ISO 8859-1 format string. This character set is a 8-bit subset of Unicode and is the most common format for strings in English and other Western European languages. As this is typically the format that the USB device's strings are in, it is recommended that the usb_string function be used instead of the usb_get_string function.

    ⇦ prev ⇱ home next ⇨
    Poster of Linux kernelThe best gift for a Linux geek