赞
踩
struct usb_dev_data { struct usb_endpoint_descriptor *ep_in; struct usb_endpoint_descriptor *ep_out; struct input_dev *input; spinlock_t lock; }; static int usb_device_probe(struct usb_interface *iface, const struct usb_device_id *id) { int i, ret; struct usb_dev_data *usb; struct usb_host_interface *alt = iface->altsetting; usb = kzalloc(sizeof(*usb), GFP_KERNEL); if (!usb) return -ENOMEM; /* 获取主机与设备通信所使用的端点 */ for (i = 0; i < alt->desc.bNumEndpoints; i++) { if (usb_endpoint_dir_in(&alt->endpoint[i].desc)) { usb->ep_in = &alt->endpoint[i].desc; } else if (usb_endpoint_dir_out(&alt->endpoint[i].desc)) { usb->ep_out = &alt->endpoint[i].desc; } } spin_lock_init(&usb->lock); /* 将上面分配的内存保存到interface的私有数据中 */ usb_set_intfdata(iface, usb); /* 先分配一个input_dev */ usb->input = input_allocate_device(sizeof(*usb)); if (!usb->input) { kfree(usb) return -ENOMEM; } xxxx /* * * */ /* 注册input device */ ret = input_register_device(usb->input); if (ret) { input_free_device(usb->input); kfree(usb); return ret; } return ret; } static void usb_device_disconnect(struct usb_interface *iface) { struct usb_dev_data *usb = usb_get_intfdata(iface); input_unregister_device(usb->input); input_free_device(usb->input); kfree(usb); } static const struct usb_device_id usb_device_id_table[] = { {USB_DEVICE(VID, PID)}, {} }; static struct usb_driver usb_device_driver = { .name = "usb_device", .probe = usb_device_probe, .disconnect = usb_device_disconnect, .id_table = usb_device_id_table }; module_usb_driver(usb_device_driver); MODULE_LICENSE("GPL");
以上是USB设备驱动的基本框架。
device_id_table用于告诉内核,这个驱动适用于哪些设备,
只有PID和VID完全匹配之后就会进入probe流程。
当设备被拔掉之后内核会执行disconnect方法。
在probe函数申明了一个struct usb_dev_data类型的指针,并为之分配了内存。
并将该指针保存到了interface的私有数据中,这个变量会在整个驱动的流程中使用到,
这里我只是在struct usb_dev_data中定义了2个变量,一个是out endpoint和in endpoint。在实际的驱动,这里还会有你需要的相应的设备结构,比如chrdev, input_dev等等。
这时候,就可以完成相应的驱动开发。
在相应的设备的私有数据中保存端点信息,收发的时候,使用usb相应的收发函数实现。今天就暂时不讲。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。