分析USB平台设备模型框架(1)
start_kernel rest_init(); kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); do_basic_setup(); driver_init(); void __init driver_init(void) void __init driver_init(void) { /* These are the core pieces */ devices_init(); 表示在/sys/devices /sys/dev /sys/block /sys/char 文件夹 buses_init(); /sys/bus classes_init(); /sys/class firmware_init(); /sys/firmware hypervisor_init(); /* These are also core pieces, but must come after the * core core pieces. */ platform_bus_init(); system_bus_init(); cpu_dev_init(); memory_dev_init(); } 平台总线设备驱动: struct bus_type platform_bus_type = { .name = "platform", .dev_attrs = platform_dev_attrs, .match = platform_match, .uevent = platform_uevent, .pm = PLATFORM_PM_OPS_PTR, }; int __init platform_bus_init(void) { int error; early_platform_cleanup(); error = device_register(&platform_bus); if (error) return error; error = bus_register(&platform_bus_type); //平台总线注冊 if (error) device_unregister(&platform_bus); return error; } USB总线设备驱动: USB总线匹配函数 static int usb_device_match(struct device *dev, struct device_driver *drv) { /* devices and interfaces are handled separately */ if (is_usb_device(dev)) { /* interface drivers never match devices */ if (!is_usb_device_driver(drv)) return 0; /* TODO: Add real matching code */ return 1; } else { struct usb_interface *intf; struct usb_driver *usb_drv; const struct usb_device_id *id; /* device drivers never match interfaces */ 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; } struct bus_type usb_bus_type = { .name = "usb", .match = usb_device_match, .uevent = usb_uevent, }; static const struct file_operations usb_fops = { .owner = THIS_MODULE, .open = usb_open, }; USB HUB驱动,因此大多数情况下,能够直接使用USB HUB设备,系统已经完毕device和driver static struct usb_driver hub_driver = { .name = "hub", .probe = hub_probe, .disconnect = hub_disconnect, .suspend = hub_suspend, .resume = hub_resume, .reset_resume = hub_reset_resume, .pre_reset = hub_pre_reset, .post_reset = hub_post_reset, .ioctl = hub_ioctl, .id_table = hub_id_table, .supports_autosuspend = 1, }; subsys_initcall(usb_init); retval = bus_register(&usb_bus_type); //USB总线注冊 priv->devices_kset = kset_create_and_add("devices", NULL,&priv->subsys.kobj); //在/sys/bus/usb下创建devices priv->drivers_kset = kset_create_and_add("drivers", NULL,&priv->subsys.kobj); //在/sys/bus/usb下创建drivers klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put); 初始化devices链表 klist_init(&priv->klist_drivers, NULL, NULL); 初始化driver链表 retval = bus_register_notifier(&usb_bus_type, &usb_bus_nb); retval = usb_host_init(); retval = usb_major_init(); //注冊字符设备 error = register_chrdev(USB_MAJOR, "usb", &usb_fops); //cat /proc/devices 下查看 180 usb,主设备号180 retval = usb_register(&usbfs_driver); retval = usb_devio_init(); retval = usbfs_init(); retval = usb_hub_init(); usb_register(&hub_driver) ///将hub.c里面的hub_driver增加到usb总线下的驱动链表里 new_driver->drvwrap.driver.bus = &usb_bus_type; //指定增加的驱动的类型: &usb_bus_type; retval = driver_register(&new_driver->drvwrap.driver); ret = bus_add_driver(drv); driver_find(drv->name, drv->bus); ret = bus_add_driver(drv); error = driver_attach(drv); bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); } driver_match_device(drv, dev) //调用总线上的match,检測驱动与设备是否匹配 driver_probe_device(drv, dev); really_probe(dev, drv); if (dev->bus->probe) { ret = dev->bus->probe(dev); //先使用总显得Probe if (ret) goto probe_failed; } else if (drv->probe) { ret = drv->probe(dev); //再使用调用hub.c里面的驱动的probe函数 if (ret) goto probe_failed; } static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) hub_configure(hub, endpoint) pipe = usb_rcvintpipe(hdev, endpoint->bEndpointAddress); maxp = usb_maxpacket(hdev, pipe, usb_pipeout(pipe)); hub->urb = usb_alloc_urb(0, GFP_KERNEL); usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq, hub, endpoint->bInterval); hub->urb->transfer_dma = hub->buffer_dma; hub->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; hub_activate(hub, HUB_INIT); static DECLARE_WAIT_QUEUE_HEAD(khubd_wait); //定义等待队列 khubd_task = kthread_run(hub_thread, NULL, "khubd"); //开启Hub_thread线程 wait_event_freezable(khubd_wait,!list_empty(&hub_event_list) ||kthread_should_stop()); //将当前进程增加到等待队列中,进程在这里停下来了,我们须要看看那里唤醒进程 void usb_kick_khubd(struct usb_device *hdev) static void kick_khubd(struct usb_hub *hub) wake_up(&khubd_wait); //唤醒等待进程Hub_thread hub_events(); hub_port_connect_change(hub, i,portstatus, portchange); udev = usb_alloc_dev(hdev, hdev->bus, port1); //分配一个struct usb_device choose_address(udev); //选择usb设备地址 hub_port_init dev_info (&udev->dev, "%s %s speed %sUSB device using %s and address %d\n", (udev->config) ? "reset" : "new", speed, type, udev->bus->controller->driver->name, devnum); hub_set_address //将选择的地址告诉usb设备 retval = usb_get_device_descriptor(udev, 8); //获得设备描写叙述符 retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE); ;//再次获得设备描写叙述符 status = usb_new_device(udev); announce_device(udev); show_string(udev, "Product", udev->product); show_string(udev, "Manufacturer", udev->manufacturer); show_string(udev, "SerialNumber", udev->serial); err = device_add(&udev->dev); error = bus_add_device(dev);;//将usb设备增加到usb总线旗下的设备列表里面 bus_attach_device(dev); ret = device_attach(dev); ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); //对全部的驱动,调用__device_attach推断设备与驱动是否匹配 driver_match_device(drv, dev) return drv->bus->match ? drv->bus->match(dev, drv) : 1; driver_probe_device(drv, dev); ret = really_probe(dev, drv); drv->probe(dev);//一旦匹配的话就会调用驱动的probe函数 描写叙述USB HUB 的结构体 struct usb_hub { struct device *intfdev; /* the "interface" device */ struct usb_device *hdev; struct kref kref; struct urb *urb; /* for interrupt polling pipe */ /* buffer for urb ... with extra space in case of babble */ char (*buffer)[8]; dma_addr_t buffer_dma; /* DMA address for buffer */ union { struct usb_hub_status hub; struct usb_port_status port; } *status; /* buffer for status reports */ struct mutex status_mutex; /* for the status buffer */ int error; /* last reported error */ int nerrors; /* track consecutive errors */ struct list_head event_list; /* hubs w/data or errs ready */ unsigned long event_bits[1]; /* status change bitmask */ unsigned long change_bits[1]; /* ports with logical connect status change */ unsigned long busy_bits[1]; /* ports being reset or resumed */ #if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */ #error event_bits[] is too short! #endif struct usb_hub_descriptor *descriptor; /* class descriptor */ struct usb_tt tt; /* Transaction Translator */ unsigned mA_per_port; /* current for each child */ unsigned limited_power:1; unsigned quiescing:1; unsigned disconnected:1; unsigned has_indicators:1; u8 indicator[USB_MAXCHILDREN]; struct delayed_work leds; struct delayed_work init_work; };
posted on 2017-04-20 18:03 gavanwanggw 阅读(255) 评论(0) 编辑 收藏 举报