http://www.cnblogs.com/lifexy/p/7641602.html
在上一章分析完USB总线驱动程序后,接下来开始写一个USB驱动:
本节目的:将USB鼠标的左键当作L按键,将USB鼠标的右键当作S按键,中键当作回车按键
参考/drivers/hid/usbhid/usbmouse.c(内核自带的USB鼠标驱动)
1、本节需要用到的宏如下:
struct usb_device_id usbmouse_id_table []=USB_INTERFACE_INFO(cl,sc,pr);
USB_INTERFACE_INFO()设置usb_driver驱动的id_table成员
cl:接口类,我们USB鼠标为HID类,所以填入0X03,也就是USB_INTERFACE_CLASS_HID
sc:接口子类为启动设备,填入USB_INTERFACE_SUBCLASS_BOOT
pr:接口协议为鼠标协议,填入USB_INTERFACE_PROTOCOL_MOUSE
struct usb_device *dev=interface_to_usbdev(intf);
通过usb_interface接口获取usb_device设备,为后面设置USB数据传输用
pipe=usb_rcvintpipe(dev,endpoint);
创建一个接受(rcv)中断(int)类型的端点管道(pipe),用来端点和数据缓冲区之间的连接,鼠标为接受中断类型
dev:usb_device设备结构体
endpoint:为端点描述符的成员endpoint->bEndpointAddress //端点地址
- 对于控制类型的端点管道使用: usb_sndctrlpipe()/usb_rcvctrlpipe()
- 对于实时类型的端点管道使用:usb_sndisocpipe()/usb_sndisocpipe()
- 对于批量类型的端点管道使用:usb_sndbulkpipe()/usb_rcvbulkpipe()
2、本节需要用到的函数如下:
usb_register(struct usb_driver *driver);
注册一个usb_driver驱动,然后内核会通过usb_driver的成员id.table函数匹配一次USB设备,匹配成功会调用USB_driver的成员.probe函数
usb_deregister(struct usb_driver *driver);
注销一个usb_driver驱动,在出口函数中写
*usb_buffer_alloc(struct usb_device *dev,size_t size,gfp_t mem_flags,dma_addr_t *dma);
分配一个usb缓冲区,该缓冲区的物理地址和虚拟地址的数据一致,分配成功返回一个char型缓冲区虚拟地址
*dev:usb_device设备结构体
size:分配的缓冲区大小,这里填端点描述符的成员endpoint->wMaxPacketSize //端点最大包长
mem_flags:分配内存的参数,这里填GFP_ATOMIC,表示从不睡眠
dma:分配成功则会返回一个DMA缓冲区物理地址
void usb_buffer_free(struct usb_device *dev,size_t size,void *addr,dma_addr_t dma);
注销分配的usb缓冲区,在usb_driver的disconnect成员