分析USB平台设备模型框架(1)

来源:互联网 发布:量化交易程序员 招聘 编辑:程序博客网 时间:2024/05/29 17:04
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/busclasses_init();                                        /sys/classfirmware_init();                                       /sys/firmwarehypervisor_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和driverstatic 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下创建devicespriv->drivers_kset = kset_create_and_add("drivers", NULL,&priv->subsys.kobj);  //在/sys/bus/usb下创建driversklist_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,主设备号180retval = 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);    //先使用总显得Probeif (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 krefkref;struct urb*urb;/* for interrupt polling pipe *//* buffer for urb ... with extra space in case of babble */char(*buffer)[8];dma_addr_tbuffer_dma;/* DMA address for buffer */union {struct usb_hub_statushub;struct usb_port_statusport;}*status;/* buffer for status reports */struct mutexstatus_mutex;/* for the status buffer */interror;/* last reported error */intnerrors;/* track consecutive errors */struct list_headevent_list;/* hubs w/data or errs ready */unsigned longevent_bits[1];/* status change bitmask */unsigned longchange_bits[1];/* ports with logical connectstatus change */unsigned longbusy_bits[1];/* ports being reset orresumed */#if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */#error event_bits[] is too short!#endifstruct usb_hub_descriptor *descriptor;/* class descriptor */struct usb_tttt;/* Transaction Translator */unsignedmA_per_port;/* current for each child */unsignedlimited_power:1;unsignedquiescing:1;unsigneddisconnected:1;unsignedhas_indicators:1;u8indicator[USB_MAXCHILDREN];struct delayed_workleds;struct delayed_workinit_work;};

0 0