Linux下USB驱动之skeleton分析

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如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzyggf.html