usbmouse的注释

来源:互联网 发布:车载蓝牙软件下载 编辑:程序博客网 时间:2024/06/03 21:10
#include <linux/kernel.h>#include <linux/slab.h>#include <linux/module.h>#include <linux/init.h>#include <linux/usb/input.h>#include <linux/hid.h>/* for apple IDs */#ifdef CONFIG_USB_HID_MODULE#include "../hid-ids.h"#endif/* * Version Information */#define DRIVER_VERSION "v1.6"#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"#define DRIVER_DESC "USB HID Boot Protocol mouse driver"#define DRIVER_LICENSE "GPL"MODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE(DRIVER_LICENSE);/*设备封装结构体*/struct usb_mouse {char name[128];/*名字*/char phys[64];/*???*/struct usb_device *usbdev; /*USB设备结构体*/struct input_dev *dev;/*输入结构体*/struct urb *irq;/*urb结构体*/signed char *data; /*数据空间*/dma_addr_t data_dma;/*dma地址*/};static void usb_mouse_irq(struct urb *urb){/*获取mouse数据,在usb_fill_int_urb这个函数里面放进去的*/struct usb_mouse *mouse = urb->context;/*获取要传输的数据空间*/signed char *data = mouse->data;/*获取输入设备结构体*/struct input_dev *dev = mouse->dev;int status;/*辨别urb的状态*/switch (urb->status) {case 0:/* success */break;case -ECONNRESET:/* unlink */case -ENOENT:case -ESHUTDOWN:return;/* -EPIPE:  should clear the halt */default:/* error */goto resubmit;}/*上报事件*/input_report_key(dev, BTN_LEFT,   data[0] & 0x01);input_report_key(dev, BTN_RIGHT,  data[0] & 0x02);input_report_key(dev, BTN_MIDDLE, data[0] & 0x04);input_report_key(dev, BTN_SIDE,   data[0] & 0x08);input_report_key(dev, BTN_EXTRA,  data[0] & 0x10);input_report_rel(dev, REL_X,     data[1]);input_report_rel(dev, REL_Y,     data[2]);input_report_rel(dev, REL_WHEEL, data[3]);/*告知内核事件上报完毕*/input_sync(dev);resubmit:status = usb_submit_urb (urb, GFP_ATOMIC);if (status)err ("can't resubmit intr, %s-%s/input0, status %d",mouse->usbdev->bus->bus_name,mouse->usbdev->devpath, status);}static int usb_mouse_open(struct input_dev *dev){/*获得mouse从dev->dev->p->private_data*/struct usb_mouse *mouse = input_get_drvdata(dev);/*有必要存在吗?*/mouse->irq->dev = mouse->usbdev;/*将urb提交到内核*/if (usb_submit_urb(mouse->irq, GFP_KERNEL))return -EIO;return 0;}static void usb_mouse_close(struct input_dev *dev){/*获得mouse从dev->dev->p->private_data*/struct usb_mouse *mouse = input_get_drvdata(dev);usb_kill_urb(mouse->irq);}/*probe函数*/static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id){/*获得接口上的usb_device结构体*/struct usb_device *dev = interface_to_usbdev(intf);/*一个接口配置结构体*/struct usb_host_interface *interface;/*端点描述符结构体*/struct usb_endpoint_descriptor *endpoint;/*自定结构体*/struct usb_mouse *mouse;/*输入结构体*/struct input_dev *input_dev;int pipe, maxp;int error = -ENOMEM;/*获取当前接口的配置*/interface = intf->cur_altsetting;/*判断当前接口的端点个数是否为1个*/if (interface->desc.bNumEndpoints != 1)return -ENODEV;/*获取端点米描述符*/endpoint = &interface->endpoint[0].desc;if (!usb_endpoint_is_int_in(endpoint))return -ENODEV;/*创建管道*/pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);/*返回这个端点的最大包的大小*/maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));/*给mouse分配空间*/mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL);/*分配input_dev空间*/input_dev = input_allocate_device();/*分配失败*/if (!mouse || !input_dev)goto fail1;/*分配数据缓冲区域的空间*/mouse->data = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &mouse->data_dma);/*分配失败*/if (!mouse->data)goto fail1;/*创建urb结构*/mouse->irq = usb_alloc_urb(0, GFP_KERNEL);/*创建失败*/if (!mouse->irq)goto fail2;mouse->usbdev = dev;mouse->dev = input_dev;/*复制制造商名字*/if (dev->manufacturer)strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name));/*产品名*/if (dev->product) { /*如果有制造商名*/if (dev->manufacturer)/*清除制造商名*/strlcat(mouse->name, " ", sizeof(mouse->name));/*复制产品名*/strlcat(mouse->name, dev->product, sizeof(mouse->name));}/*如果鼠标名没有*/if (!strlen(mouse->name))snprintf(mouse->name, sizeof(mouse->name), "USB HIDBP Mouse %04x:%04x", le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct));/*用来获取USB设备在Sysfs里面的路径*/usb_make_path(dev, mouse->phys, sizeof(mouse->phys));strlcat(mouse->phys, "/input0", sizeof(mouse->phys));/*填充input_dev结构体*/input_dev->name = mouse->name;input_dev->phys = mouse->phys;usb_to_input_id(dev, &input_dev->id);input_dev->dev.parent = &intf->dev;/*设置支持哪些类型的事件,按键,相对坐标*/input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);/*设置按键事件*/input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);/*设置相对坐标事件*/input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) |BIT_MASK(BTN_EXTRA);input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);/*将mouse放入到input_dev->dev->p->private_data里面*/input_set_drvdata(input_dev, mouse);/*设置回调函数*/input_dev->open = usb_mouse_open;input_dev->close = usb_mouse_close;/*填充urb结构体*/usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data, (maxp > 8 ? 8 : maxp), usb_mouse_irq, mouse, endpoint->bInterval);/*设置urb中的dma地址*/mouse->irq->transfer_dma = mouse->data_dma;/*设置urb的flags标志位*/mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;/*注册输入设备*/error = input_register_device(mouse->dev);if (error)goto fail3;/*将mouse数据放到intf->dev->p->private_data里面*/usb_set_intfdata(intf, mouse);return 0;fail3:usb_free_urb(mouse->irq);fail2:usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);fail1:input_free_device(input_dev);kfree(mouse);return error;}static void usb_mouse_disconnect(struct usb_interface *intf){/*从intf->p->private_data里面获取mouse的数据*/struct usb_mouse *mouse = usb_get_intfdata (intf);/*清除intf->p->private_data里面的数据*/usb_set_intfdata(intf, NULL);/*如果mouse这个数据是存在的*/if (mouse) {/*清除mouse中的urb*/usb_kill_urb(mouse->irq);/*卸载输入设备*/input_unregister_device(mouse->dev);/*释放urb的空间*/usb_free_urb(mouse->irq);/*释放缓冲区的空间*/usb_buffer_free(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);/*释放鼠标的空间*/kfree(mouse);}}/*定义了鼠标这一类设备*/static struct usb_device_id usb_mouse_id_table [] = {{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,USB_INTERFACE_PROTOCOL_MOUSE) },{ }/* Terminating entry */};MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);static struct usb_driver usb_mouse_driver = {.name= "usbmouse",.probe= usb_mouse_probe,.disconnect= usb_mouse_disconnect,.id_table= usb_mouse_id_table,};static int __init usb_mouse_init(void){/*注册鼠标的usb_driver*/int retval = usb_register(&usb_mouse_driver);if (retval == 0)printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"DRIVER_DESC "\n");return retval;}static void __exit usb_mouse_exit(void){/*卸载鼠标的usb_driver*/usb_deregister(&usb_mouse_driver);}module_init(usb_mouse_init);module_exit(usb_mouse_exit);

原创粉丝点击