Usb_skeleton.c,是USB驱动的框架,适合USB驱动的初学者。
1.结构体
内核其实就是一坨坨的数据结构,加上一根根链表。
对于初学者,如果直接看USB驱动代码,大概会被那些名字相近的结构体弄得晕头转向,比如usb_host_interface和usb_interface,看着看着就把两个混淆了。所以,在学习USB驱动之前,建议把相关结构体都拎出来看一下,其实,也就那么几个结构体在那装神弄鬼。USB skeleton驱动中用到的主要字段已用蓝色标出:
endpoint:
struct usb_host_endpoint {
struct usb_endpoint_descriptor desc; struct list_head urb_list; void *hcpriv; unsigned char *extra; int extralen;};
struct usb_endpoint_descriptor {
__u8 bLength; __u8 bDescriptorType;__u8 bEndpointAddress;
__u8 bmAttributes;
__le16 wMaxPacketSize;
__u8 bInterval;
__u8 bRefresh; __u8 bSynchAddress;} __attribute__ ((packed));
bEndpointAddress,最高位用来判断传输方向:
#define USB_ENDPOINT_NUMBER_MASK 0x0f
#define USB_ENDPOINT_DIR_MASK 0x80
#define USB_DIR_OUT 0
#define USB_DIR_IN 0x80
bmAttributes,表示endpoint的类型:
#define USB_ENDPOINT_XFERTYPE_MASK 0x03
#define USB_ENDPOINT_XFER_CONTROL 0
#define USB_ENDPOINT_XFER_ISOC 1
#define USB_ENDPOINT_XFER_BULK 2
#define USB_ENDPOINT_XFER_INT 3
bInterval,如果该endpoint是interrupt类型的(USB鼠标驱动就是该类型),那么bInterval就表示中断时间间隔,单位毫秒。
interface:
struct usb_interface {
struct usb_host_interface *altsetting; struct usb_host_interface *cur_altsetting; unsigned num_altsetting; int minor; enum usb_interface_condition condition; struct device dev; struct class_device *class_dev;};
struct usb_host_interface {
struct usb_interface_descriptor desc; struct usb_host_endpoint *endpoint; char *string; unsigned char *extra; int extralen;};
struct usb_interface_descriptor {
__u8 bLength; __u8 bDescriptorType; __u8 bInterfaceNumber; __u8 bAlternateSetting; __u8 bNumEndpoints; __u8 bInterfaceClass; __u8 bInterfaceSubClass; __u8 bInterfaceProtocol; __u8 iInterface;} __attribute__ ((packed));
usb_device:
struct usb_device {
int devnum;
char devpath [16]; enum usb_device_state state; enum usb_device_speed speed; struct usb_tt *tt; int ttport; struct semaphore serialize; unsigned int toggle[2]; struct usb_device *parent; struct usb_bus *bus; struct usb_host_endpoint ep0; struct device dev; struct usb_device_descriptor descriptor; struct usb_host_config *config; struct usb_host_config *actconfig; struct usb_host_endpoint *ep_in[16]; struct usb_host_endpoint *ep_out[16]; char **rawdescriptors; int have_langid; int string_langid; char *product; char *manufacturer; char *serial; struct list_head filelist; struct dentry *usbfs_dentry; int maxchild; struct usb_device *children[USB_MAXCHILDREN];};
usb_driver:
struct usb_driver {
struct module *owner; const char *name; int (*probe) (struct usb_interface *intf, const struct usb_device_id *id); void (*disconnect) (struct usb_interface *intf); int (*ioctl) (struct usb_interface *intf, unsigned int code, void *buf); int (*suspend) (struct usb_interface *intf, pm_message_t message); int (*resume) (struct usb_interface *intf); const struct usb_device_id *id_table; struct device_driver driver;};
2.Init
先来看模块初始化函数,它仅仅完成一个功能,那就是注册USB驱动:
static int __init usb_skel_init(void)
{
int result; result = usb_register(&skel_driver); if (result) err("usb_register failed. Error number %d", result); return result;}
其中,skel_driver如下: