USB Drivers Ted Baker Andy Wang COP 5641 / CIS 4930.

87
USB Drivers Ted Baker Andy Wang COP 5641 / CIS 4930

Transcript of USB Drivers Ted Baker Andy Wang COP 5641 / CIS 4930.

Page 1: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB Drivers

Ted Baker Andy Wang

COP 5641 / CIS 4930

Page 2: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB Device Basics

Universal Serial Bus (USB) connects between a computer and peripheral devices Created to replace various slow buses

(parallel, serial, and keyboard connections) Can support up to 480Mb/s A tree built out of point-to-point links

Links are four-wire cables (ground, power, and two signal wires)

Page 3: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB Device Basics

A USB device can never start sending data without first being asked by the host controller

Single-master implementation Host polls various devices A device can request a fixed bandwidth (for audio

and video I/O)

Page 4: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB Device Basics

USB protocol defines a set of standards that any device can follow No need to write a driver for a device that is in

a predefined class and follows that standard, Predefined classes: storage devices,

keyboards, mice, joysticks, network devices, and modems

No defined standard for video devices and USB-to-serial devices

A driver is needed for every device

Page 5: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB Device Basics

Linux supports two types of USB drivers Drivers on a host system

Control the USB devices that are plugged into it Drivers on a device (USB gadget drivers)

Control how that single device looks to the host computer as a USB device

Page 6: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB Device Basics

Different kernel

subsystems

An interface for USB drivers to

access HW

Page 7: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB Device Basics

USB drivers bind to interfaces, not

the device

Page 8: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB Overview

A USB device has one or more configurations E.g., power and bandwidth requirements

A configuration has one or more interfaces E.g., audio data, knobs for speakers

An interface has one or more settings Different quality of services

E.g., different frame sizes for digital cameras Also zero or more endpoints

E.g., bulk, interrupt endpoints.

Page 9: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Endpoints

The most basic form of USB communication is through an endpoint Carries data in one direction

From the host to device (OUT endpoint) From the device to the host (IN endpoint)

Page 10: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Endpoints

Four endpoint types CONTROL

Used for configuring the device, retrieving information and status about the device, or sending commands to the device

Every device has a control endpoint called endpoint 0

Used by USB core to configure the device at insertion time

Transfers are guaranteed with reserved bandwidth

Page 11: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Endpoints

INTERRUPT Transfer small amounts of data at a fixed rate For USB keyboards and mice Also used to control the device Not for large transfers Guaranteed reserved bandwidth

Page 12: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Endpoints

BULK Transfer large amounts of data No data loss Not time guaranteed A BULK packet might be split up across multiple

transfers Used for printers, storage, and network devices

Page 13: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Endpoints

ISOCHRONOUS Transfer large amount of data No guarantees (potential data loss) For real-time data collections, A/V devices

Control and bulk endpoints are used for asynchronous data transfers

Interrupt and isochronous endpoints are periodic with reserved bandwidth

Page 14: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Endpoints

Endpoint information is in struct usb_endpoint_descriptor embedded in struct usb_host_endpoint

Some important fields bEndpointAddress (8-bit)

Use USB_DIR_OUT and USB_DIR_IN bit masks to determine the direction of data flow

Page 15: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Endpoints

bmAttributes Type of the endpoint & USB_ENDPOINT_XFERTYPE_MASK to

determine if the endpoint is of type USB_ENDPOINT_XFER_ISOC, USB_ENDPOINT_XFER_BULK, or USB_ENDPOINT_XFER_INT

wMaxPacketSize Maximum bytes that an endpoint can handle Larger transfers will be split into multiple transfers

Page 16: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Endpoints

bInterval For interrupt endpoints, this value specifies the

milliseconds between interrupt requests for the endpoint

Page 17: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Interfaces

USB endpoints are bundled into interfaces A interface handles only one type of logical

connection (e.g., a mouse) Some devices have multiple interfaces

E.g., a speaker One interface for buttons and one for audio stream

USB interface may have alternate settings E.g., different settings to reserve different

amounts of bandwidth for the device

Page 18: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Interfaces

Described via struct usb_interface Passed from USB core to USB drivers

Some important fields struct usb_host_interface *altsetting

An array of settings for this interface unsigned num_altsetting

Number of alternative settings

Page 19: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Interfaces

struct usb_host_interface *cur_altsetting A pointer into the altsetting array, denoting

the current setting int minor

Minor number assigned by the USB core to the interface

Valid after a successful call to usb_register_dev

Page 20: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Configurations

USB interfaces are bundled into configurations

A USB device can have multiple configurations Might switch between them

Described in struct usb_host_config embedded in struct usb_device

Page 21: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB and Sysfs

Both USB devices and its interfaces are shown in sysfs as individual devices

A USB mouse device can be represented as /sys/devices/pci0000:00/0000:00:09.0/usb2/2-1

The interface of the USB mouse device driver is represented as/sys/devices/pci0000:00/0000:00:09.0/usb2/2-1/2-1:1.0

root_hub-hub_port:configuration.interface

Page 22: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB and Sysfs

For a two-level USB connection, the device name is in the following format

root_hub-hub_port-hub_port:configuration.interface

In the sysfs directory, all USB information is available E.g., idVendor, idProduct, bMaxPower bConfigurationValue can be written to

change the active configuration

Page 23: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB and Sysfs

More information is available in /proc/bus/usb directory

User-space programs can directly communicate with USB devices via the directory

Page 24: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB Urbs (USB Request Block)

struct urb Used to send and receive data between

endpoints Asynchronous Defined in <include/linux/usb.h> Dynamically created

Contains reference count for garbage collection Designed to achieve high throughput

Page 25: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB Urbs (USB Request Block)

A typical lifecycle of a urb A USB device driver creates a urb

Assigns it to a specific endpoint of a device Submits it to the USB core

The USB core submits the urb to specific USB host controller driver

The USB host controller driver processes the urb and transfers it to the device

Notifies the USB device driver when the urb is done

Page 26: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB Urbs (USB Request Block)

A urb can be cancelled by the driver or the USB core if the device is removed from the system

Page 27: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

struct urb

Important fields/* destination USB device */

/* must be initialized by the USB driver before the urb can be sent to the USB core */

struct usb_device *dev;

/* end point type information */

/* set to the return value from one of the usb send and receive pipe functions */

/* must be initialized by the USB driver before the urb can be sent to the USB core */

unsigned int pipe;

Page 28: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

struct urb

/* assigned to one of the transfer flags */

unsigned int transfer_flags;

void *transfer_buffer; /* points to a kmalloced buffer */

dma_addr_t transfer_dma; /* buffer for DMA transfers */

/* buffer length for either the transfer_buffer or the transfer_dma variable, 0 if neither buffers are used */

int transfer_buffer_length;

/* pointer to a setup packet for a control urb */

/* transferred before the data in the transfer buffer */

unsigned char *setup_packet;

/* DMA buffer for the setup packet for a control urb */

dma_addr_t setup_dma;

Page 29: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

struct urb

/* pointer to the completion handler called by USB core */

usb_complete_t complete;

/* pointer to a data blob that can be set by the USB driver */

void *context;

/* actual length of data sent/received by the urb */

int actual_length;

/* accessed in the completion handler */

/* see status values */

int status;

/* the initial frame number for isochronous transfers */

int start_frame;

Page 30: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

struct urb

/* polling interval for the urb */

/* valid only for interrupt or isochronous urbs */

/* for slow devices, the unit is in frames or milliseconds */

/* for other devices, the unit is in 1/8 milliseconds */

int interval;

/* the number of isochronous transfer buffers handled by this urb */

/* must be set by the USB driver before the urb is sent to the USB core */

int number_of_packets;

/* number of isochronous transfers with errors */

int error_count;

Page 31: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

struct urb

/* allows a single urb to define a number of isochronous transfers at once */

struct usb_iso_packet_descriptor iso_frame_desc[0];

struct usb_iso_packet_descriptor {

unsigned int offset; /* byte into the transfer buffer */

unsigned int length; /* length of the transfer buffer */

/* length of data received into the transfer buffer */

unsigned int actual_length;

unsigned int status; /* see status values */

};

Page 32: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB send and receive pipe functions

/* specifies a control OUT endpoint for the specified USB device with the specified endpoint number */

unsigned int usb_sndctrlpipe(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_rcvctrlpipe(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_sndbulkpipe(struct usb_device *dev,

unsigned int endpoint);

Page 33: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB send and receive pipe functions

/* specifies a bulk IN endpoint for the specified USB device with the specified endpoint number */

unsigned int usb_rcvbulkpipe(struct usb_device *dev,

unsigned int endpoint);

/* specifies a interrupt OUT endpoint for the specified USB device with the specified endpoint number */

unsigned int usb_sndintpipe(struct usb_device *dev,

unsigned int endpoint);

/* specifies a interrupt IN endpoint for the specified USB device with the specified endpoint number */

unsigned int usb_rcvintpipe(struct usb_device *dev,

unsigned int endpoint);

Page 34: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB send and receive pipe functions

/* specifies a isochronous OUT endpoint for the specified USB device with the specified endpoint number */

unsigned int usb_sndisocpipe(struct usb_device *dev,

unsigned int endpoint);

/* specifies a isochronous IN endpoint for the specified USB device with the specified endpoint number */

unsigned int usb_rcvisocpipe(struct usb_device *dev,

unsigned int endpoint);

Page 35: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Transfer flags

URB_SHORT_NOT_OK Partial read should be treated as an error by

the USB core URB_ISO_ASAP

If the driver wants the isochronous urb to be scheduled as soon as bandwidth allows

Set the start_frame variable

Page 36: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Transfer flags

URB_NO_TRANSFER_DMA_MAP Set when the urb contains a DMA buffer to be

transferred Tells the USB core to use the buffer pointed

by the transfer_dma pointer, not the transfer_buffer pointer

Page 37: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Transfer flags

URB_NO_SETUP_DMA_MAP Used for control urbs with DMA buffer already

set up Tells the USB core to use the buffer pointed

by the setup_dma pointer instead of the setup_packet pointer

URB_ASYNC_UNLINK Tells usb_unlink_urb() to return

immediate and unlink the urb in the background

Page 38: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Transfer flags

URB_NO_FSBR For UHCI USB host controller Generally not used

URB_ZERO_PACKET Tells a bulk out urb finishes by sending an

empty packet when the data is aligned to an endpoint packet boundary

Page 39: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Transfer flags

URB_NO_INTERRUPT Indicates that the HW may not generate an

interrupt when the urb is finished Used when queuing multiple urbs to the same

endpoint Used by USB core to perform DMA transfers

Page 40: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Status Values

0 The urb transfer was successful For isochronous urbs, only indicates whether

the urb has been unlinked Detailed status in iso_frame_desc

-ENOENT Urb stopped by usb_kill_urb

-ECONNRESET Urb was unlinked by usb_unlink_urb transfer_flags set to URB_ASYNC_UNLINK

Page 41: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Status Values

-EINPROGRESS Urb still being processed by the USB host

controller A bug if seen at the driver level

-EPROTO (a HW problem) A bitstuff error happened during the transfer No response packet was received

-EILSEQ (a HW problem) CRC mismatch

Page 42: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Status Values

-EPIPE The endpoint is now stalled If not a control endpoint, can clear this error with usb_clear_halt

-ECOMM Data received faster than it could be written to

system memory -ENOSR

Data cannot be retrieved from the system memory during the transfer fast enough to keep up with the requested USB data rate

Page 43: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Status Values

-EOVERFLOW (a HW problem) When the endpoint receives more data than

the specified max -EREMOTEIO

Full amount of data was not received Occurs when the URB_SHORT_NOT_OK is set

-ENODEV The USB device is gone from the system

Page 44: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Status Values

-EXDEV Only for a isochronous urb Transfer was partially completed

-EINVAL ISO madness, if this happens: Log off and go

home Incorrect function parameter

Page 45: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Status Values

-ESHUTDOWN Host controller driver has been disabled or

disconnected Urb was submitted after the device was

removed Configuration change while the urb was

submitted

Page 46: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Creating and Destroying Urbs

All urbs need to be created dynamically Or the reference count would not work To create a urb, callstruct urb *usb_alloc_urb(int iso_packets,

gfp_t mem_flags);

Returns a pointer to the urb or NULL on failure iso_packets: number of isochronous

packets this urb should contain mem_flags: same as kmalloc flags

To destroy a urb, callvoid usb_free_urb(struct urb *urb);

Page 47: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Interrupt urbs

To initialize an interrupt urb, callvoid

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);

urb: a pointer to the urb to be initialized dev: The destination USB device pipe: the destination endpoint of this urb

Page 48: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Interrupt urbs

transfer_buffer: a pointer to a kmalloced buffer

buffer_length: the length of the transfer buffer

complete: pointer to the completion handler context: pointer to the blob, retrieved by the

completion handler function interval: scheduling interval for this urb

Page 49: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Bulk urbs

To initialize an bulk urb, call 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);

Similar to interrupt urb initialization No interval parameter

Page 50: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Control urbs

To initialize a control urb, callvoid

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);

Similar to bulk urb initialization setup_packet: points to the setup packet data Does not set the transfer_flags

Page 51: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Isochronous urbs

Have no initialization functions Need to be initialized by hand

/* from /drivers/media/video/usbvideo/konicawc.c */

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;

}

New location for 2.6.25

Page 52: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Submitting Urbs

To send a urb to the USB core, callint usb_submit_urb(struct urb *urb, gfp_t mem_flags);

urb: a pointer to the urb mem_flags: same as kmalloc flags Should not access a submitted urb until the complete function is called

Page 53: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Completing Urbs: The Completion Callback Handler Called exactly once when the urb is

completed When this function is called, the USB core is

finished with the urb, and control is returned to the device driver

Page 54: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Completing Urbs: The Completion Callback Handler The completion handler is called under three

conditions The urb is successfully sent to the device and

acknowledged An error has occurred

Check the status variable The urb was unlinked (the submission was

cancelled) when a device is removed from the system

Page 55: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Canceling Urbs

To stop a submitted urb, callint usb_kill_urb(struct urb *urb);

Used when the device is disconnected from the system

int usb_unlink_urb(struct urb *urb);

Tells the USB core to stop an urb Returns before the urb is fully stopped

Useful while in an interrupt handler Requires setting the URB_ASYNC_UNLINK

Page 56: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Writing a USB Driver

Similar to a pci_driver Driver registers its driver object with the USB

subsystem Later uses vendor and device identifiers to tell

if its hardware has been installed

Page 57: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

What Devices Does the Driver Support? struct usb_device_id lists supported

types of USB devices Important fields

__u16 match_flags Determines which fields in the structure the

device should be matched against Check include/linux/mod_devicetable.h

__u16 idVendor __u16 idProduct

Page 58: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

What Devices Does the Driver Support?

__u16 bcdDevice_lo __u16 bcdDevice_hi

Define low and high ends of the range of the vendor-assigned product version number

Expressed in binary-coded decimal (BCD) __u8 bDeviceClass __u8 bDeviceSubClass __u8 bDeviceProtocol

Define the class, subclass, and protocol of the device

Page 59: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

What Devices Does the Driver Support?

__u8 bInterfaceClass __u8 bInterfaceSubClass __u8 bInterfaceProtocol

Class, subclass, and protocol of the individual interface

kernel_ulong_t driver_info Used to differentiate different devices in the

probe callback function

Page 60: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

What Devices Does the Driver Support? To initialize usb_device_id, use the

following macrosUSB_DEVICE(vendor, product)

Creates a usb_device_id that can be used to match only the specified vendor and product IDs

USB_DEVICE_VER(vendor, product, lo, hi)

Creates a usb_device_id that can be used to match only the specified vendor and product IDs within a version range

USB_DEVICE_INFO(class, subclass, protocol)

Creates a usb_device_id that can be used to match a specific class of USB devices

Page 61: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

What Devices Does the Driver Support?

USB_INTERFACE_INFO(class, subclass, protocol)

Creates a usb_device_id that can be used to match a specific class of USB interfaces

Example/* table of devices that work with this driver */

static struct usb_device_id skel_table[] = {

{ USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },

{ } /* Terminating entry */

};

/* allow user-space tools to figure out what devices this driver can control */

MODULE_DEVICE_TABLE(usb, skel_table);

Page 62: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Registering a USB Driver

The main structure for a USB driver is struct usb_driver

Important fields struct module *owner

Set to THIS_MODULE to track the reference count of the module owning this driver

const char *name

Points to a unique driver name

Page 63: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Registering a USB Driver

const struct usb_device_id *id_table

Pointer to the list of supported USB devices If you want your driver always be called for every

USB device, create an entry that sets only the driver_info field

static struct usb_device_id usb_ids[] = {

{.driver_info = 42},

{ }

};

Page 64: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Registering a USB Driver

int (*probe) (struct usb_interface *intf,

const struct usb_device_id *id)

Called when the USB core thinks it has a struct usb_interface that this driver can handle

The USB driver should initialize the usb interface and return 0, or return a negative error number on failure

void (*disconnect) (struct usb_interface *intf)

Called when the usb_interface has been removed from the system, or when the driver is being unloaded

Page 65: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Registering a USB Driver

To create a struct usb_driver, only five fields need to be initialized

static struct usb_driver skel_driver = {

.owner = THIS_MODULE,

.name = "skeleton",

.id_table = skel_table,

.probe = skel_probe,

.disconnect = skel_disconnect,

};

Page 66: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Registering a USB Driver

To register a USB driver call usb_register_driver

Example

static int __init usb_skel_init(void) {

int result;

/* register this driver with the USB subsystem */

result = usb_register(&skel_driver);

if (result)

err("usb_register failed. Error number %d", result);

return result;

}

Page 67: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Registering a USB Driver

To unload a USB driver call usb_deregister

Example

static void __exit usb_skel_exit(void) {

/* deregister this driver with the USB subsystem */

/* invokes disconnect() within usb_deregister() */

usb_deregister(&skel_driver);

}

Page 68: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Probe and Disconnect in Detail

Called in the context of the USB hub kernel thread Sleep is allowed However, should do most of the work when

the device is opened by a user USB core handles addition and removal of USB

devices in a single thread A slow device driver can slow down USB device

detection

Page 69: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Probe and Disconnect in Detail

Probe function should Initialize local structures that it might use to

manage the USB device Save any information that it needs to the local

structure Detect endpoint address and buffer sizes Example usb/usb-skeleton.c

Page 70: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Probe and Disconnect in Detail

static int skel_prob(struct usb_interface *interface,

const struct usb_device_id *id) {

struct usb_skel *dev = NULL;

struct usb_host_interface *iface_desc;

struct usb_endpoint_descriptor *endpoint;

size_t buffer_size;

int i;

int retval = -ENOMEM;

dev = kmalloc(sizeof(struct usb_skel), GFP_KERNEL);

if (dev == NULL) {

err(“Out of memory”);

goto error;

}

memset(dev, 0x00, sizeof(*dev));

kref_init(&dev->kref);

Page 71: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Probe and Disconnect in Detail

dev->udev = usb_get_dev(interface_to_usbdev(interface));

dev->interface = interface;

/* set up the endpoint information */

/* use only the first bulk-in and bulk-out endpoints */

iface_desc = interface->cur_altsetting;

for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {

endpoint = &iface_desc->endpoint[i].desc;

if (!dev->bulk_in_endpointAddr &&

(endpoint->bEndpointAddress & USB_DIR_IN) &&

((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)

== USB_ENDPOINT_XFER_BULK)) {

/* we found a bulk in endpoint */

Page 72: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Probe and Disconnect in Detail

/* we found a bulk in endpoint */

buffer_size = endpoint->wMaxPacketSize;

dev->bulk_in_size = buffer_size;

dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;

dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);

if (!dev->bulk_in_buffer) {

err("Could not allocate bulk_in_buffer");

goto error;

}

}

if (!dev->bulk_out_endpointAddr &&

!(endpoint->bEndpointAddress & USB_DIR_IN) &&

((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)

== USB_ENDPOINT_XFER_BULK)) {

/* we found a bulk out endpoint */

Page 73: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Probe and Disconnect in Detail

/* we found a bulk out endpoint */

dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;

}

}

if (!(dev->bulk_in_endpointAddr &&

dev->bulk_out_endpointAddr)) {

err("Could not find both bulk-in and bulk-out endpoints");

goto error;

}

/* save our data pointer in this interface device */

usb_set_intfdata(interface, dev);

Use usb_get_intfdata(interface) to retrieve dev

Page 74: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Probe and Disconnect in Detail

/* we can register the device now, as it is ready */

retval = usb_register_dev(interface, &skel_class);

if (retval) {

err(“Not able to get a minor for this device.”);

usb_set_intfdata(interface, NULL);

goto error;

}

return 0;

error:

if (dev)

kref_put(&dev->kref, skel_delete);

return retval;

}

Need to call usb_register_dev()

instead of usb_register() for input, tty, video USB devices that are not

associated with predefined types

Call usb_put_dev(), free bulk_in_buffer

and dev

Page 75: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Probe and Disconnect in Detail

The definition of skel_classstatic struct usb_class_driver skel_class = { .name = "usb/skel%d", .fops = &skel_fops, .mode = S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH, .minor_base = USB_SKEL_MINOR_BASE,};

The definition of skel_fopsstatic struct file_operations skel_fops = { .owner = THIS_MODULE, .read = skel_read, .write = skel_write, .open = skel_open, .release = skel_release,};

The start of the assigned minor range for this

driver

Page 76: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Probe and Disconnect in Detail

The disconnect functionstatic void skel_disconnect(struct usb_interface *interface) {

struct usb_skel *dev;

int minor = interface->minor;

/* prevent skel_open() from racing skel_disconnect() */

lock_kernel();

dev = usb_get_intfdata(interface);

usb_set_intfdata(interface, NULL);

/* give back our minor */

usb_deregister_dev(interface, &skel_class);

unlock_kernel();

/* decrement our usage count */

kref_put(&dev->kref, skel_delete);

}

The big kernel lock

All in-transit urbs are canceled by the USB

core before disconnect() is called; no need to

call usb_kill_urb()

Page 77: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Submitting and Controlling a Urb

static ssize_t skel_write(struct file *file,

const char __user *user_buffer,

size_t count, loff_t *ppos) {

struct usb_skel *dev;

int retval = 0;

struct urb *urb = NULL;

char *buf = NULL;

if (count == 0) goto exit;

dev = (struct usb_skel *)file->private_data;

/* create a urb and its buffer; copy the data to the urb */

urb = usb_alloc_urb(0, GFP_KERNEL);

if (!urb) {

retval = -ENOMEM;

goto error;

}

Initialized in skel_open()

Page 78: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Submitting and Controlling a Urb

buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL,

&urb->transfer_dma);

if (!buf) {

retval = -ENOMEM;

goto error;

}

if (copy_from_user(buf, user_buffer, count)) {

retval = -EFAULT;

goto error;

}

/* initialize the urb properly */

usb_fill_bulk_urb(urb, dev->udev,

usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),

buf, count, skel_write_bulk_callback, dev);

urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

Page 79: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Submitting and Controlling a Urb

/* send the data out the bulk port */

retval = usb_submit_urb(urb, GFP_KERNEL);

if (retval) {

err("%s - failed submitting write urb, error %d",

__FUNCTION__, retval);

goto error;

}

/* release our reference to this urb, the USB core will

eventually free it entirely */

usb_free_urb(urb);

exit:

return count;

Page 80: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Submitting and Controlling a Urb

error:

usb_buffer_free(dev->udev, count, buf, urb->transfer_dma);

usb_free_urb(urb);

kfree(buf);

return retval;

}

Page 81: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Probe and Disconnect in Detail

The callback (complete) functionstatic void skel_write_bulk_callback(struct urb *urb,

struct pt_regs *regs) {

/* in interrupt context */

/* sync/async unlink faults aren't errors */

if (urb->status && !(urb->status == -ENOENT ||

urb->status == -ECONNRESET ||

urb->status == -ESHUTDOWN)) {

dbg("%s - nonzero write bulk status received: %d",

__FUNCTION__, urb->status);

}

/* free up our allocated buffer */

usb_buffer_free(urb->dev, urb->transfer_buffer_length,

urb->transfer_buffer, urb->transfer_dma);

}

Page 82: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB Transfers Without Urbs

usb_bulk_msg Creates a USB bulk urb and sends it to the

specified device Waits for it to complete before returning to the

callerint usb_bulk_msg(struct usb_device *usb_dev,

unsigned int pipe, void *data, int len,

int *actual_length, int timeout);

timeout in jiffies Set to 0 to wait until the message to complete

Page 83: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB Transfers Without Urbs

Cannot be called from within interrupt context Cannot be called with a spinlock held Cannot be cancelled by any other function The disconnect call needs to wait for usb_bulk_msg to complete before allowing itself to be unloaded

Page 84: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB Transfers Without Urbs

Examplestatic ssize_t skel_read(struct file *file,

char __user *buffer, size_t count,

loff_t *ppos) {

struct usb_skel *dev;

int retval = 0;

dev = (struct usb_skel *)file->private_data;

/* 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);

Page 85: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

USB Transfers Without Urbs

/* if successful read, copy the data to user space */

if (!retval) {

if (copy_to_user(buffer, dev->bulk_in_buffer, count))

retval = -EFAULT;

else

retval = count;

}

return retval;

}

Page 86: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

usb_control_msg

Works just like the usb_bulk_msg Allows a driver to send and receive USB

control messagesint usb_control_msg(struct usb_device *dev,

unsigned int pipe, __u8 request,

__u8 requesttype, __u16 value,

__u16 index, void *data, __u16 size,

int timeout);

Returns the number of bytes transferred on success, or a negative error number

Same restrictions as usb_bulk_msg

Page 87: USB Drivers Ted Baker  Andy Wang COP 5641 / CIS 4930.

Other USB Data Functions

Cannot be called from within interrupt context or with a spinlock held

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

int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index,

void *buf, int size);