1、模型
USB总线:
struct bus_type usb_bus_type = {
.name = "usb",
.match = usb_device_match,
.uevent = usb_uevent,
#ifdef CONFIG_USB_SUSPEND
.pm = &usb_bus_pm_ops,
#endif
};
USB设备模型:usb_device结构体,通过两个函数实现,即usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)和usb_new_device(struct usb_device *udev)函数。
USB驱动模型:usb_driver结构体,通过函数usb_register(struct usb_driver *driver)来实现。
3、USB总线注册在:
static int __init usb_init(void)
retval = bus_register(&usb_bus_type);
USB设备注册:我们内核已经含有一个主机控制器驱动(也叫做USB总线驱动),主机控制器包含有一个HUB接口,当我们把USB设备插入HUB接口的时候,就会产生中断:
hub_irq(struct urb *urb)
kick_khubd(hub); //kick就是踢的意思,表示HUB有动作了
wake_up(&khubd_wait); //唤醒线程,HUB活动的处理事件,内核创建了一个线程来专门负责的!
static int hub_thread(void *__unused)
{
do {
hub_events(); //hub事件调用
wait_event_freezable(khubd_wait, //唤醒
!list_empty(&hub_event_list) ||
kthread_should_stop());
} while (!kthread_should_stop() || !list_empty(&hub_event_list));
}
HUB事件调用具体如下:
hub_events(void)
hub_port_connect_change(hub, i,portstatus, portchange);
usb_alloc_dev(hdev, hdev->bus, port1); //USB设备分配函数
hub_port_init(hub, udev, port1, i);
usb_control_msg(udev, usb_rcvaddr0pipe(),USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,USB_DT_DEVICE << 8, 0,buf,GET_DESCRIPTOR_BUFSIZE,initial_descriptor_timeout); //获取USB设备设备描述符,使用0地址来获取
hub_set_address(udev, devnum); //给USB设备分配一个唯一的地址
retval = usb_get_device_descriptor(udev, 8); //再次获取设备描述符,知道端点0的最大传输包大小
retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);
status = usb_new_device(udev); //这里将注册USB设备
err = usb_enumerate_device(udev); //把多有描述符读取出来
err = usb_get_configuration(udev);
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, length); //读取所有描述符
usb_parse_configuration(dev, cfgno, &dev->config[cfgno], bigbuffer, length); //解析所有描述符并填充结构体
err = device_add(&udev->dev); //将通过USB总线的匹配函数来匹配USB驱动,匹配成功调用driver驱动(不是usb_driver)的probe函数!
4、USB总线匹配函数:
static int usb_device_match(struct device *dev, struct device_driver *drv)
{
。。。。。。。。。。
id = usb_match_id(intf, usb_drv->id_table);
if (id)
return 1;
。。。。。。。。。。。。
return 0;
}
匹配的原则就是驱动的id_table和恰年描述解析出来接口描述符进行匹配,切记是接口,而不是USB设备!!!
5、匹配成功调用USB驱动的driver驱动的probe函数,切记是driver而不是usb_driver
那么driver如何和usb_driver挂钩,看驱动的注册过程:
usb_register(struct usb_driver *driver)
usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
new_driver->drvwrap.driver.probe = usb_probe_interface; //driver内嵌在usb_driver的
retval = driver_register(&new_driver->drvwrap.driver); //注册usb_driver.driver
所以USB总线匹配成功是调用函数usb_probe_interface,这一点很重要!!!
usb_probe_interface(struct device *dev)
id = usb_match_id(intf, driver->id_table); //得到匹配的接口
error = driver->probe(intf, id); //这里才调用usb_driver的配备函数,参数是匹配的接口intf
到这里USB架构就搞定