Usb 子系统初始化和驱动绑定流程
2015-03-04 11:30
281 查看
Usb子系统的入口函数在kernel/drivers/usb/core/usb.c
kernel_imx/drivers/usb/core/hub.c
error = bus_add_device(dev); //把这个设备添加到usb总线;
bus_probe_device(dev); //为设备匹配一个驱动;}
= 0;}}
static int __init usb_init(void) { //其实usb设备都连接到hub上面的;主要就是监控hub端口的状态变化; retval = usb_hub_init(); //khubd监控线程就在这个函数里;监控hub接口的状态改变; }
kernel_imx/drivers/usb/core/hub.c
int usb_hub_init(void) { //hub_thread(khubd)监控线程起来了,khubd线程就是监控usb端口状态的变化;;ps -aux | grep khubd 可以查看; khubd_task = kthread_run(hub_thread, NULL, "khubd"); if (!IS_ERR(khubd_task)) return 0; }
static int hub_thread(void *__unused) { do { //最主要的就是録ub_events()函数;监控端口状态函数就在它里面; hub_events(); } while (!kthread_should_stop() || !list_empty(&hub_event_list)); }
<pre name="code" class="cpp">static void hub_events(void) { <span style="white-space:pre"> </span>//usb_interface在usb驱动中很重要; intf = to_usb_interface(hub_dev); <span style="white-space:pre"> </span>//从usb设备得到usb端口; <span style="white-space:pre"> </span>if (connect_change){
<span style="white-space:pre"> </span>//这个函数是主要函数; <span style="white-space:pre"> </span>hub_port_connect_change(hub, i, portstatus, portchange); //连接usb设备就会调用这个函数; } }
static void hub_port_connect_change(struct usb_hub *hub, int port1, u16 portstatus, u16 portchange) { <span style="white-space:pre"> </span>/* reset (non-USB 3.0 devices) and get descriptor */ status = hub_port_init(hub, udev, port1, i); <span style="white-space:pre"> </span>f (!status) { //打印设备信息,添加设备到usb总线,获取设备描述符,绑定驱动在这个函数里; status = usb_new_device(udev); } }
int usb_new_device(struct usb_device *udev) { <span style="white-space:pre"> </span>//枚举设备;即读取设备描述符; err = usb_enumerate_device(udev); /* Read descriptors */ <span style="white-space:pre"> </span>announce_device(udev); <span style="white-space:pre"> </span>//打印新设备连接信息(vid/pid等)需要打开"make menuconfig -> Device drivers -> usb support -> usb verbose debug messages"; <span style="white-space:pre"> </span>err = device_add(&udev->dev); //注册usb设备;并会查找驱动链表绑定一个驱动; }
<pre name="code" class="cpp" style="orphans: 2; widows: 2;">//kernel/drivers/base/core.cint device_add(struct device *dev)
<span style="font-family: Tahoma; text-align: -webkit-auto;">{</span>
error = bus_add_device(dev); //把这个设备添加到usb总线;
bus_probe_device(dev); //为设备匹配一个驱动;}
<pre name="code" class="cpp" style="font-size:14px; orphans: 2; widows: 2;">//kernel/drivers/base/bus.cvoid bus_probe_device(struct device *dev){struct bus_type *bus = dev->bus;int ret;if (bus && bus->p->drivers_autoprobe) {ret = device_attach(dev); //查找设备驱动;WARN_ON(ret < 0);}}
<pre name="code" class="cpp" style="font-size:14px; orphans: 2; widows: 2;">//kernel/drivers/base/db.cint device_attach(struct device *dev){if (dev->driver) {//为usb设备查找匹配的驱动;if (klist_node_attached(&dev->p->knode_driver)) {ret = 1;goto out_unlock;}ret = device_bind_driver(dev); //usb设备和驱动绑定;if (ret == 0)ret = 1;else {dev->driver = NULL;ret
= 0;}}
int device_bind_driver(struct device *dev) { int ret; ret = driver_sysfs_add(dev); if (!ret) driver_bound(dev); //设备和驱动绑定; return ret; }
static void driver_bound(struct device *dev) { if (klist_node_attached(&dev->p->knode_driver)) { printk(KERN_WARNING "%s: device %s already bound\n", __func__, kobject_name(&dev->kobj)); return; } pr_debug("driver: '%s': %s: bound to device '%s'\n", dev_name(dev), __func__, dev->driver->name); klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices); if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_BOUND_DRIVER, dev); }
相关文章推荐
- 从USB设备插上到驱动probe调用流程分析
- Linux下usb驱动调用流程
- 树莓派uboot的串口初始化(uboot驱动结构 1主要流程)
- USB 3G网卡驱动流程
- Android4.0 USB挂载内核驱动层流程分析(二)
- usb网卡驱动分析(一)——设备初始化
- LINUX驱动之SPI子系统之三基本的调用流程
- Linux驱动学习笔记----------input输入子系统(基本概念与流程)
- kernel 3.0.31 usb_init 子系统初始化过程分析
- 2410上NAND的初始化及驱动流程
- USB驱动Suspend&Resume 调用流程分析
- 要开始系统学习LINUX USB驱动了(通用的驱动流程)
- Linux下USB 输入子系统的学习(以鼠标驱动为例)
- USB设备驱动之设备初始化(设备枚举)
- LINUX驱动之SPI子系统之四spi_master的注册流程
- Linux usb子系统(一) _写一个usb鼠标驱动
- USB子系统学习之基础篇二(驱动组织和结构)
- atheros无线驱动初始化流程
- Android4.0 USB挂载内核驱动层流程分析(三)
- linux驱动之input子系统之按键驱动编写流程(三)