Linux usb子系统(一)(5)

下面是内核"drdrivers/hid/usbhid/usbmouse.c"中的ib_table填写方式, 可以看出, 不仅构造使用了宏, 由于USB鼠标是标准设备, 它的属性值也有标准的宏来标识

230 static struct usb_device_id usb_mouse_id_table [] = { 231 { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT, 232 USB_INTERFACE_PROTOCOL_MOUSE) }, 233 { } /* Terminating entry */ 234 }; USB鼠标实例

内核"drivers/hid/usbhid/usbmouse.c"就是一个usb鼠标的驱动, 这里我根据自己的理解写了一个, 采用的是"usb中断设备驱动+input子系统"框架

#define BUF_SIZE 8 MODULE_LICENSE("GPL"); //面向对象, 根据需求封装类 struct xj_mouse { char name[128]; struct usb_device *dev; struct urb *msg; struct input_dev *input; signed char *buf; }; struct xj_mouse *mouse; static int usb_mouse_open(struct input_dev *dev) { struct xj_mouse *mouse = input_get_drvdata(dev); mouse->msg->dev = mouse->dev; if (usb_submit_urb(mouse->msg, GFP_KERNEL)) return -EIO; return 0; } static void usb_mouse_close(struct input_dev *dev) { struct xj_mouse *mouse = input_get_drvdata(dev); usb_kill_urb(mouse->msg); } static int init_input(struct usb_interface * intf) { int err=0; struct usb_device *dev = mouse->dev; struct input_dev *input_dev = mouse->input; input_dev->name = mouse->name; 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); input_set_drvdata(input_dev, mouse); input_dev->open = usb_mouse_open; input_dev->close = usb_mouse_close; err = input_register_device(mouse->input); return 0; } static void completion(struct urb * msg) { int status; signed char *buf = mouse->buf; struct input_dev *input = mouse->input; input_report_key(input, BTN_LEFT, buf[0] & 0x01); input_report_key(input, BTN_RIGHT, buf[0] & 0x02); input_report_key(input, BTN_MIDDLE, buf[0] & 0x04); input_report_key(input, BTN_SIDE, buf[0] & 0x08); input_report_key(input, BTN_EXTRA, buf[0] & 0x10); input_report_rel(input, REL_X, buf[1]); input_report_rel(input, REL_Y, buf[2]); input_report_rel(input, REL_WHEEL, buf[3]); input_sync(input); status = usb_submit_urb (msg, GFP_ATOMIC); } static int probe(struct usb_interface *intf, const struct usb_device_id *id) { int pipe; struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; //分配、初始化个性结构 mouse = (struct xj_mouse *)kzalloc(sizeof(struct xj_mouse),GFP_KERNEL); mouse->dev=interface_to_usbdev(intf); mouse->msg=usb_alloc_urb(0,GFP_KERNEL); mouse->input=input_allocate_device(); mouse->buf=(void *)kzalloc(BUF_SIZE,GFP_KERNEL); if (mouse->dev->manufacturer){ strlcpy(mouse->name, mouse->dev->manufacturer, sizeof(mouse->name)); mouse->input->name = mouse->name; } //初始化input设备 init_input(intf); //获取pipe interface=intf->cur_altsetting; endpoint=&interface->endpoint[0].desc; /* 使用dev和endpoint获取端点地址 */ pipe = usb_rcvintpipe(mouse->dev,endpoint->bEndpointAddress); //注册usb驱动 usb_fill_int_urb(mouse->msg,mouse->dev,pipe,mouse->buf,BUF_SIZE,completion,mouse->msg,endpoint->bInterval); return 0; } static void disconnect(struct usb_interface *intf) { struct xj_mouse *tmp_mouse = usb_get_intfdata (intf); usb_set_intfdata(intf, NULL); if (tmp_mouse) { usb_kill_urb(tmp_mouse->msg); input_unregister_device(tmp_mouse->input); usb_free_urb(tmp_mouse->msg); kfree(tmp_mouse->buf); kfree(tmp_mouse); } } static struct usb_device_id id_table [] ={ { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,USB_INTERFACE_PROTOCOL_MOUSE) }, {}, }; struct usb_driver mouse_drv = { .name = "xj_mouse_drv", .probe = probe, .disconnect = disconnect, .id_table = id_table, }; module_usb_driver(mouse_drv);

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

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