转载地址:http://blog.youkuaiyun.com/Deadline_h/article/details/78709142
1.usb总线设备模型
linux usb子系统使用的总线设备驱动模型。
在linux内核里有一条usb总线为usb_bus_type
struct bus_type usb_bus_type = {
.name = "usb",
.match = usb_device_match,
.uevent = usb_uevent,
}
在该总线下挂有usb设备和usb驱动。
根据设备和驱动的类型又分为两大类
一类为usb设备,一类为usb接口设备。
usb设备和usb设备驱动进行匹配,usb接口设备和usb接口驱动进行匹配。
通过match函数,这两类的匹配进入不同的分支
static int usb_device_match(struct device *dev, struct device_driver *drv)
{
if (is_usb_device(dev)) {
if (!is_usb_device_driver(drv))
return 0;
return 1;
} else if (is_usb_interface(dev)) {
struct usb_interface *intf;
struct usb_driver *usb_drv;
const struct usb_device_id *id;
if (is_usb_device_driver(drv))
return 0;
intf = to_usb_interface(dev);
usb_drv = to_usb_driver(drv);
id = usb_match_id(intf, usb_drv->id_table);
if (id)
return 1;
id = usb_match_dynamic_id(intf, usb_drv);
if (id)
return 1;
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
/* ———————————————— */
usb接口设备(设备类型 == usb_if_device_type) 通过 device_add注册
usb接口驱动(struct usb_driver ,需要我们实现) 通过 usb_register 注册
/* ———————————————— */
usb设备(设备类型 == usb_device_type) 通过 device_add 注册
usb设备驱动() 通过usb_register_device_driver()注册
2.usb设备接入过程
1、usb设备插入usb接口,usb差分信号线上电平变化,导致usb控制器产生中断hub_irq,通知系统有usb设备接入。
2、usb hub线程(hub_thread)被hub_irq唤醒,发生如下函数调用
hub_irq
kick_khubd
hub_thread
hub_events
hub_port_connect_change
udev = usb_alloc_dev
hub_port_init
usb_new_device(udev)
usb_enumerate_device
usb_get_configuration
for(; cfgno < ncfg; cfgno++)
{
usb_get_descriptor
usb_parse_configuration
usb_parse_interface
usb_parse_endpoint
}
device_add(注册的设备类型是:usb_device_type)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
usb设备驱动在哪里注册?
在/driver/usb/core/usb.c注册
struct usb_device_driver usb_generic_driver = {
.name = "usb",
.probe = generic_probe,
.disconnect = generic_disconnect,
#ifdef CONFIG_PM
.suspend = generic_suspend,
.resume = generic_resume,
#endif
.supports_autosuspend = 1,
};
usb_init
usb_register_device_driver(&usb_generic_driver )
generic_probe
usb_set_configuration
for (i = 0; i < nintf; ++i)
{
struct usb_interface *intf = cp->interface[i];
。。。
intf->dev.bus = &usb_bus_type;
intf->dev.type = &usb_if_device_type;
ret = device_add(&intf->dev);
。。。
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
从上述代码中可知,在接入usb设备引发如下事件
注册usb设备 -> 根据usb设备的接口描述符,注册usb接口设备(有多少个接口就有多少个usb接口设备)
所以我们要实现接口设备驱动用来驱动usb接口设备(类型为usb_if_device_type的设备)
3 usb接口设备驱动编写
参考:h:\linux_source_code\linux-3.0.1\drivers\hid\usbhid\Usbmouse.c
static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
int pipe;
interface = intf->cur_altsetting;
endpoint = &interface->endpoint[0].desc;
uk_dev = input_allocate_device();
set_bit(EV_KEY, uk_dev->evbit);
set_bit(EV_REP, uk_dev->evbit);
set_bit(KEY_L, uk_dev->keybit);
set_bit(KEY_S, uk_dev->keybit);
set_bit(KEY_ENTER, uk_dev->keybit);
input_register_device(uk_dev);
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
len = endpoint->wMaxPacketSize;
usb_buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &usb_buf_phys);
uk_urb = usb_alloc_urb(0, GFP_KERNEL);
usb_fill_int_urb(uk_urb, dev, pipe, usb_buf, len, usbmouse_as_key_irq, NULL, endpoint->bInterval);
uk_urb->transfer_dma = usb_buf_phys;
uk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
usb_submit_urb(uk_urb, GFP_KERNEL);
return 0;
}
static struct usb_device_id usb_mouse_id_table [] = {
{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
USB_INTERFACE_PROTOCOL_MOUSE) },
{ }
};
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)
{
int retval = usb_register(&usb_mouse_driver);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
大致讲这么多,仅供参考。