usb driver

设备和控制器之间的关系:The USB host controller is in charge of asking every USB device if it has any data to send.Because of thistopology, a USB device can never start sending data without first being asked to by the host controller.

usb总线特点:The bus is very simple at the technological level, as it's a single-master implementation in which the host computer polls the various peripheral devices. Despite this intrinsic limitation, the bus has some interesting features, such as the ability for a device to request a fixed bandwidth for its data transfers in order to reliably support video and audio I/O. Another important feature of USB is that it acts merely as a communication channel between the device and the host, without requiring specific meaning or structure to the data it delivers.

标准设备可以不用重新编写驱动:The USB protocol specifications define a set of standards that any device of a specific type can follow. If a device follows that standard, then a special driver for that device is not necessary. These different types are called classes and consist of things likestorage devices, keyboards, mice, joysticks, network devices, and modems. Video devices and USB-to-serial devices are a good example where there is no defined standard, and a driver is needed for every different device from different manufacturers.

usb驱动可以分为两种:The Linux kernel supports two main types of USB drivers: drivers on a host system and drivers on a device.

一 关键数据结构

1.endpoint:

传输都是通过ep进行:The most basic form of USB communication is through something called an endpoint. A USB endpoint can carry data in only one direction, either from the host computer to the device (called anOUT endpoint) or from the device to the host computer (called anIN endpoint). Endpoints can be thought of as unidirectional pipes.()

种类:

CONTROL They are commonly used for configuring the device, retrieving information about the device, sending commands to the device, or retrieving status reports about the device. Every USB device has a control endpoint called "endpoint 0" that is used by the USB core to configure the device at insertion time.

INTERRUPT Interrupt endpoints transfer small amounts of data at a fixed rate every time the USB host asks the device for data. These endpoints are the primary transport method for USB keyboards and mice.

BULK  They are common for devices that need to transfer any data that must get through with no data loss.These endpoints are common on printers, storage, and network devices.
ISOCHRONOUS These endpoints are used in devices that can handle loss of data, and rely more on keeping a constant stream of data flowing. Real-time data collections, such as audio and video devices, almost always use these endpoints.

Control and bulk endpoints are used for asynchronous data transfers, whenever the driver decides to use them. Interrupt and isochronous endpoints are periodic.

struct usb_endpoint_descriptor:

bEndpointAddress 地址

bmAttributes  类型,是in或者out

wMaxPacketSize 支持的最大数据包大小

bInterval  中断请求时间间隔

2. interface

USB endpoints are bundled up intointerfaces.  USB interfaces handle only one type of a USB logical connection, such as a mouse, a keyboard, or a audio stream.Because a USB interface represents basic functionality,each USB driver controls an interface

USB interfaces may have alternate settings, which are different choices for parameters of the interface.Alternate settings can be used to control individual endpoints in different ways, such as to reserve different amounts of USB bandwidth for the device.

struct usb_interface

int minor  If the USB driver bound to this interface uses the USB major number, this variable contains the minor number assigned by the USB core to the interface. This is valid only after a successful call tousb_register_dev

3. Configurations

USB interfaces are themselves bundled up intoconfigurations. A USB device can have multiple configurations and might switch between them in order to change the state of the device.

Linux describes USB configurations with the structurestruct usb_host_config and entire USB devices with the structurestruct usb_device. USB device drivers do not generally ever need to read or write to any values in these structures

二 和sysfs的关系

Both the physical USB device (as represented by a struct usb_device) and the individual USB interfaces (as represented by astruct usb_interface) are shown in sysfs as individual devices.

The first USB device is a root hub. This is the USB controller, usually contained in a PCI device. The controller is so named because it controls the whole USB bus connected to it. The controller is a bridge between the PCI bus and the USB bus, as well as being the first USB device on that bus.

the USB sysfs device naming scheme is:

root_hub-hub_port:config.interface


all of the USB specific information is available directly through sysfs (for example, the idVendor, idProduct, and bMaxPower information). One of these files,bConfigurationValue, can be written to in order to change the active USB configuration that is being used.

Sysfs does not expose all of the different parts of a USB device, as it stops at the interface level.More information can be found in theusbfs filesystem, which is mounted in the /proc/bus/usb/ directory on the system.

The file /proc/bus/usb/devices does show all of the same information exposed in sysfs, as well as the alternate configuration and endpoint information for all USB devices that are present in the system.

三 urb

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. 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 andcontain an internal reference count that enables them to be automatically freed when the last user of the urb releases it.

1. struct urb

struct usb_device *dev 发送到哪个设备

unsigned int pipe  发送到哪个ep,该成员用usb_sndctrlpipe等函数来设置

unsigned int transfer_flags 

void *transfer_buffer 

dma_addr_t transfer_dma

unsigned char *setup_packet  control ep用

dma_addr_t setup_dma

usb_complete_t complete  传输结束的回调函数,由usb core调用

void *context

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

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.

int number_of_packets  Valid only for isochronous urbs and specifies the number of isochronous transfer buffers to be handled by this urb.

int error_count 

struct usb_iso_packet_descriptor iso_frame_desc[0]  Valid only for isochronous urbs. 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.

2.Creating and Destroying Urbs

The struct urb must be created with a call to theusb_alloc_urb function。

struct urb *usb_alloc_urb(int iso_packets, int mem_flags);


In order to tell the USB core that the driver is finished with the urb, the driver must call theusb_free_urb function

void usb_free_urb(struct urb *urb);


Isochronous urbs unfortunately do not have an initializer function like the interrupt, control, and bulk urbs do.

3. Submitting Urbs

int usb_submit_urb(struct urb *urb, int mem_flags);

4. Completing Urbs: The Completion Callback Handler

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, thestatus 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 thestatus 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 tousb_unlink_urb or usb_kill_urb, or when a device is removed from the system and a urb had been submitted to it.

5. Canceling Urbs

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.

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.

四 写驱动

1. 识别

The struct usb_device_id structure provides a list of different types of USB devices that this driver supports. This list is used by the USB core to decide which driver to give a device to, andby the hotplug scripts to decide which driver to automatically load when a specific device is plugged into the system.

USB_DEVICE(vendor, product)等可以用来创建该结构

the MODULE_DEVICE_TABLE macro is necessary to allow user-space tools to figure out what devices this driver can control. And the stringusb must be the first value in the macro.

2. Registering a USB Driver

struct usb_driver

struct module *owner 

Pointer to the module owner of this driver. The USB core uses it to properly reference count this USB driver so that it is not unloaded at inopportune moments. The variable should be set to theTHIS_MODULE macro.

const char *name 

Pointer to the name of the driver. It must be unique among all USB drivers in the kernel and is normally set to the same name as the module name of the driver. It shows up in sysfs under/sys/bus/usb/drivers/ when the driver is in the kernel.

const struct usb_device_id *id_table If this variable is not set, theprobe function callback in the USB driver is never called. If you want your driver always to be called for every USB device in the system, create a entry that sets only thedriver_info field

int (*probe) (struct usb_interface *intf, const struct usb_device_id *id)

called by the USB core when it thinks it has astruct usb_interface that this driver can handle.If the USB driver claims thestruct usb_interface that is passed to it, it should initialize the device properly and return0. If the driver does not want to claim the device, or an error occurs, it should return a negative error value.
void (*disconnect) (struct usb_interface *intf)

called by the USB core when thestruct usb_interface has been removed from the system or when the driver is being unloaded from the USB core.

int (*ioctl) (struct usb_interface *intf, unsigned int code, void *buf)

If it is present, it is called when a user-space program makes a ioctl call on theusbfs filesystem device entry associated with a USB device attached to this USB driver.

To register the structusb_driver with the USB core, a call tousb_register_driver is made with a pointer to thestruct usb_driver. This is traditionally done in the module initialization code for the USB driver

3. probe and disconnect in Detail

The probe function is called when a device is installed that the USB core thinks this driver should handle; theprobe function should perform checks on the information passed to it about the device and decide whether the driver is really appropriate for that device. Thedisconnect function is called when the driver should no longer control the device for some reason and can do clean-up.

In the probe function callback, the USB driver should initialize any local structures that it might use to manage the USB device. It should also save any information that it needs about the device to the local structure, as it is usually easier to do so at this time.

usb_set_intfdata(interface, dev); save it

usb_get_intfdata is usually called in theopen function of the USB driver and again in thedisconnect function.

If the USB driver is not associated with another type of subsystem that handles the user interaction with the device (such as input, tty, video, etc.), the driver can use the USB major number in order to use the traditional char driver interface with user space. To do this, the USB driver must call theusb_register_dev function in the probe function when it wants to register a device with the USB core.

The usb_register_dev function requires a pointer to a struct usb_interface and a pointer to a struct usb_class_driver. This struct usb_class_driver is used to define a number of different parameters that the USB driver wants the USB core to know when registering for a minor number. This structure consists of the following variables:

char *name The name that sysfs uses to describe the device.If the number of the device needs to be in the name, the characters %d should be in the name string.

struct file_operations *fops; Pointer to the struct file_operations that this driver has defined to use to register as the character device.

mode_t mode;  The mode for the devfs file to be created for this driver; unused otherwise.

int minor_base;  This is the start of the assigned minor range for this driver. All devices associated with this driver are created with unique, increasing minor numbers beginning with this value. 

4. Submitting and Controlling a Urb

五 不用urb的传输

1. usb_bulk_msg

int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,

                 void *data, int len, int *actual_length,

                 int timeout);


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.

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.

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


 

_ _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.


3. Other USB Data Functions

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


 

unsigned char type

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

unsigned char index

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


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

                   unsigned char index, void *buf, int size);


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.

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.


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值