USB主机控制器驱动——OHCI分析

USB主机控制器驱动——OHCI分析

http://blog.csdn.net/lizuobin2/ https://blog.csdn.net/lizuobin2/article/details/51931161

    本文以 2440-ohci 驱动为例,简单分析 USB 主机控制器驱动 根 Hub 的注册过程,以及 USB设备的枚举过程,并不涉及USB协议,单纯分析驱动框架流程。无论是hub还是普通的usb设备,它们注册到 usb_bus_type 都会经历两次 Match ,因为第一次注册进来时,是将整个设备作为一个 device 注册,然后在通用的 devices 驱动程序 usb_generic_driver 的 generic_probe 函数中,将该设备的所有接口进行设置并将这些接口注册到 usb_bus_type 。如果是Hub设备的接口,则会调用 hub_probe,如果是其他设备则调用 xx_probe 函数。如果是 Hub 的话,usb主机会监测hub端口变化,如果有变化会分配一个usb_devices 注册到 usb_bus_type 重复前边的步骤。    

    首先,整个驱动框架的开始,是基于 platform 平台总线的。

 
  1. struct platform_device s3c_device_usb = {

  2. .name = "s3c2410-ohci",

  3. .id = -1,

  4. .num_resources = ARRAY_SIZE(s3c_usb_resource),

  5. .resource = s3c_usb_resource,

  6. .dev = {

  7. .dma_mask = &s3c_device_usb_dmamask,

  8. .coherent_dma_mask = 0xffffffffUL

  9. }

  10. };

 
  1. static struct platform_driver ohci_hcd_s3c2410_driver = {

  2. .probe = ohci_hcd_s3c2410_drv_probe,

  3. .remove = ohci_hcd_s3c2410_drv_remove,

  4. .shutdown = usb_hcd_platform_shutdown,

  5. /*.suspend = ohci_hcd_s3c2410_drv_suspend, */

  6. /*.resume = ohci_hcd_s3c2410_drv_resume, */

  7. .driver = {

  8. .owner = THIS_MODULE,

  9. .name = "s3c2410-ohci",

  10. },

  11. };

    platform 平台总线模型,这里定义了 platform_device 和 platform_driver ,后面将这俩注册到 platform_bus_type 时,就会根据它们的名字来匹配,显然,它们的名字都是 “s3c2410-ohci” ,匹配成功后,便会调用到 ohci_hcd_s3c2410_drv_probe 函数。在看 probe 函数之前,我们先看看设备侧提供的信息。

 
  1. static struct resource s3c_usb_resource[] = {

  2. [0] = {

  3. .start = S3C_PA_USBHOST,

  4. .end = S3C_PA_USBHOST + 0x100 - 1,

  5. .flags = IORESOURCE_MEM,

  6. },

  7. [1] = {

  8. .start = IRQ_USBH,

  9. .end = IRQ_USBH,

  10. .flags = IORESOURCE_IRQ,

  11. }

  12. };

    resource 中指定了 2440 主机控制器的寄存器范围,以及中断。

 
  1. int usb_simtec_init(void)

  2. {

  3. s3c_device_usb.dev.platform_data = &usb_simtec_info;

  4. }

  5.  
  6.  
  7. static struct s3c2410_hcd_info usb_simtec_info = {

  8. .port[0] = {

  9. .flags = S3C_HCDFLG_USED

  10. },

  11. .port[1] = {

  12. .flags = S3C_HCDFLG_USED

  13. },

  14.  
  15. .power_control = usb_simtec_powercontrol,

  16. .enable_oc = usb_simtec_enableoc,

  17. };

    这里,指定了一些额外的信息,保存在 dev.platform_data 中,后边我们再来看他们是干什么用的。下面来看 probe 函数。

 
  1. static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)

  2. {

  3. return usb_hcd_s3c2410_probe(&ohci_s3c2410_hc_driver, pdev);

  4. }

 
  1. static int usb_hcd_s3c2410_probe (const struct hc_driver *driver,

  2. struct platform_device *dev)

  3. {

  4. struct usb_hcd *hcd = NULL;

  5. int retval;

  6.  
  7. /* 设置GPG4输出1 mini2440 jz2440好像均不需要 */

  8. s3c2410_usb_set_power(dev->dev.platform_data, 1, 1);

  9. s3c2410_usb_set_power(dev->dev.platform_data, 2, 1);

  10.  
  11. /* 创建usb_hcd 绑定 usb_driver等 */

  12. hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx");

  13.  
  14. /* 主机控制寄存器 起始地址 结束地址 */

  15. hcd->rsrc_start = dev->resource[0].start;

  16. hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;

  17.  
  18. /* 申请IO空间 */

  19. if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {

  20. ...

  21. }

  22. /* 获得usb-host 时钟 */

  23. clk = clk_get(&dev->dev, "usb-host");

  24. /* 获得 usb-bus-host 时钟 */

  25. usb_clk = clk_get(&dev->dev, "usb-bus-host");

  26. /* 使能时钟 使能过流检查 */

  27. s3c2410_start_hc(dev, hcd);

  28. /* Ioremap */

  29. hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);

  30.  
  31. ohci_hcd_init(hcd_to_ohci(hcd));

  32.  
  33. retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED);

  34.  
  35. return 0;

  36.  
  37. }

    前边第一个 probe 函数仅仅是一个中转,usb_hcd_s3c2410_probe 它才是真正的 probe 函数,主要工作就是分配一个 usb_hcd 结构、设置然后 usb_add_hcd 。

 
  1. struct usb_hcd {

  2.  
  3. /*

  4. * housekeeping

  5. */

  6. struct usb_bus self; /* hcd is-a bus */

  7. struct kref kref; /* reference counter */

  8.  
  9. const char *product_desc; /* product/vendor string */

  10. char irq_descr[24]; /* driver + bus # */

  11.  
  12. struct timer_list rh_timer; /* drives root-hub polling */

  13. struct urb *status_urb; /* the current status urb */

  14. #ifdef CONFIG_PM

  15. struct work_struct wakeup_work; /* for remote wakeup */

  16. #endif

  17.  
  18. /*

  19. * hardware info/state

  20. */

  21. const struct hc_driver *driver; /* hw-specific hooks */

  22.  
  23. /* Flags that need to be manipulated atomically */

  24. unsigned long flags;

  25. #define HCD_FLAG_HW_ACCESSIBLE 0x00000001

  26. #define HCD_FLAG_SAW_IRQ 0x00000002

  27.  
  28. unsigned rh_registered:1;/* is root hub registered? */

  29.  
  30. /* The next flag is a stopgap, to be removed when all the HCDs

  31. * support the new root-hub polling mechanism. */

  32. unsigned uses_new_polling:1;

  33. unsigned poll_rh:1; /* poll for rh status? */

  34. unsigned poll_pending:1; /* status has changed? */

  35. unsigned wireless:1; /* Wireless USB HCD */

  36. unsigned authorized_default:1;

  37. unsigned has_tt:1; /* Integrated TT in root hub */

  38.  
  39. int irq; /* irq allocated */

  40. void __iomem *regs; /* device memory/io */

  41. u64 rsrc_start; /* memory/io resource start */

  42. u64 rsrc_len; /* memory/io resource length */

  43. unsigned power_budget; /* in mA, 0 = no limit */

  44.  
  45. #define HCD_BUFFER_POOLS 4

  46. struct dma_pool *pool [HCD_BUFFER_POOLS];

  47.  
  48. int state;

  49. # define __ACTIVE 0x01

  50. # define __SUSPEND 0x04

  51. # define __TRANSIENT 0x80

  52.  
  53. # define HC_STATE_HALT 0

  54. # define HC_STATE_RUNNING (__ACTIVE)

  55. # define HC_STATE_QUIESCING (__SUSPEND|__TRANSIENT|__ACTIVE)

  56. # define HC_STATE_RESUMING (__SUSPEND|__TRANSIENT)

  57. # define HC_STATE_SUSPENDED (__SUSPEND)

  58.  
  59. #define HC_IS_RUNNING(state) ((state) & __ACTIVE)

  60. #define HC_IS_SUSPENDED(state) ((state) & __SUSPEND)

  61.  
  62. /* more shared queuing code would be good; it should support

  63. * smarter scheduling, handle transaction translators, etc;

  64. * input size of periodic table to an interrupt scheduler.

  65. * (ohci 32, uhci 1024, ehci 256/512/1024).

  66. */

  67.  
  68. /* The HC driver's private data is stored at the end of

  69. * this structure.

  70. */

  71. unsigned long hcd_priv[0]

  72. __attribute__ ((aligned(sizeof(unsigned long))));

  73. };

    usb_hcd —— USB Host Controller Driver,同时,一个主机控制器驱动对应一条 usb_bus 。

 
  1. struct usb_bus {

  2. struct device *controller; /* host/master side hardware */

  3. int busnum; /* Bus number (in order of reg) */

  4. const char *bus_name; /* stable id (PCI slot_name etc) */

  5. u8 uses_dma; /* Does the host controller use DMA? */

  6. u8 otg_port; /* 0, or number of OTG/HNP port */

  7. unsigned is_b_host:1; /* true during some HNP roleswitches */

  8. unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */

  9.  
  10. int devnum_next; /* Next open device number in

  11. * round-robin allocation */

  12.  
  13. struct usb_devmap devmap; /* device address allocation map */

  14. struct usb_device *root_hub; /* Root hub */

  15. struct list_head bus_list; /* list of busses */

  16.  
  17. int bandwidth_allocated; /* on this bus: how much of the time

  18. * reserved for periodic (intr/iso)

  19. * requests is used, on average?

  20. * Units: microseconds/frame.

  21. * Limits: Full/low speed reserve 90%,

  22. * while high speed reserves 80%.

  23. */

  24. int bandwidth_int_reqs; /* number of Interrupt requests */

  25. int bandwidth_isoc_reqs; /* number of Isoc. requests */

  26.  
  27. #ifdef CONFIG_USB_DEVICEFS

  28. struct dentry *usbfs_dentry; /* usbfs dentry entry for the bus */

  29. #endif

  30.  
  31. #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)

  32. struct mon_bus *mon_bus; /* non-null when associated */

  33. int monitored; /* non-zero when monitored */

  34. #endif

  35. };

    hcd的分配过程

 
  1. struct usb_hcd *usb_create_hcd (const struct hc_driver *driver,

  2. struct device *dev, const char *bus_name)

  3. {

  4. struct usb_hcd *hcd;

  5.  
  6. /* 分配一个 usb_hcd + driver->hcd_priv_size 空间 */

  7. hcd = kzalloc(sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL);

  8.  
  9. /* dev->p->driver_data = hcd; */

  10. dev_set_drvdata(dev, hcd);

  11.  
  12. kref_init(&hcd->kref);

  13.  
  14. /* 初始化 usb_bus ,一个主机控制器对应一个 usb_bus */

  15. usb_bus_init(&hcd->self);

  16.  
  17. /* 设置 usb_bus */

  18. hcd->self.controller = dev;

  19. hcd->self.bus_name = bus_name;

  20. hcd->self.uses_dma = (dev->dma_mask != NULL);

  21.  
  22. /* 初始化 根Hub poll定时器 */

  23. init_timer(&hcd->rh_timer);

  24. hcd->rh_timer.function = rh_timer_func;

  25. hcd->rh_timer.data = (unsigned long) hcd;

  26. #ifdef CONFIG_PM

  27. INIT_WORK(&hcd->wakeup_work, hcd_resume_work);

  28. #endif

  29. /* 绑定 hc_driver */

  30. hcd->driver = driver;

  31. hcd->product_desc = (driver->product_desc) ? driver->product_desc :

  32. "USB Host Controller";

  33. return hcd;

  34. }

 
  1. static void usb_bus_init (struct usb_bus *bus)

  2. {

  3. memset (&bus->devmap, 0, sizeof(struct usb_devmap));

  4.  
  5. bus->devnum_next = 1;

  6.  
  7. bus->root_hub = NULL;

  8. bus->busnum = -1;

  9. bus->bandwidth_allocated = 0;

  10. bus->bandwidth_int_reqs = 0;

  11. bus->bandwidth_isoc_reqs = 0;

  12.  
  13. INIT_LIST_HEAD (&bus->bus_list);

  14. }

整个Probe函数里干了那些事:

    1、创建一个 usb_hcd

    2、usb_bus_init ,初始化 usb_hcd 对应的 usb_bus ,bus->devmap 清零,根 Hub 指向 NULL等

    3、设置 usb_hcd.usb_bus 

      3.1 hcd.usb_bus.controller = s3c_device_usb.dev (最开始创建的平台device)

      3.2 hcd.usb_bus.name = “s3c24xx”

    4、设置 usb_hcd.rh_timer

    5、设置 usb_hcd.driver = ohci_s3c2410_hc_driver 

    6、根据 resource 资源,设置usb_hcd.rsrc_start、usb_hcd.rsrc_len

    7、使能时钟

    8、ioremap 、申请 io 空间

    9、usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED)

 
  1. int usb_add_hcd(struct usb_hcd *hcd,

  2. unsigned int irqnum, unsigned long irqflags)

  3. {

  4. int retval;

  5. struct usb_device *rhdev;

  6. /* 无线USB? */

  7. hcd->authorized_default = hcd->wireless? 0 : 1;

  8. set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);

  9.  
  10. /* hcd->pool[i] = dma_pool_create(name, hcd->self.controller,size, size, 0); */

  11. if ((retval = hcd_buffer_create(hcd)) != 0) {

  12. ...

  13. }

  14. /*

  15. * busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1);

  16. * bus->busnum = busnum;

  17. * list_add (&bus->bus_list, &usb_bus_list);

  18. */

  19. if ((retval = usb_register_bus(&hcd->self)) < 0)

  20. goto err_register_bus;

  21. /* 根 Hub */

  22. if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) {

  23. ...

  24. }

  25.  
  26. rhdev->speed = USB_SPEED_FULL;

  27.  
  28. hcd->self.root_hub = rhdev;

  29.  
  30. /* dev->power.can_wakeup = dev->power.should_wakeup = 1 */

  31. device_init_wakeup(&rhdev->dev, 1);

  32.  
  33. if (hcd->driver->irq) {

  34.  
  35. snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",

  36. hcd->driver->description, hcd->self.busnum);

  37.  
  38. if ((retval = request_irq(irqnum, &usb_hcd_irq, irqflags,

  39. hcd->irq_descr, hcd)) != 0) {

  40. ...

  41. }

  42. hcd->irq = irqnum;

  43. }

  44.  
  45. hcd->driver->start(hcd));

  46.  
  47.  
  48. /* starting here, usbcore will pay attention to this root hub */

  49. rhdev->bus_mA = min(500u, hcd->power_budget);

  50. if ((retval = register_root_hub(hcd)) != 0)

  51. goto err_register_root_hub;

  52.  
  53. retval = sysfs_create_group(&rhdev->dev.kobj, &usb_bus_attr_group);

  54.  
  55. if (hcd->uses_new_polling && hcd->poll_rh)

  56. usb_hcd_poll_rh_status(hcd);

  57. return retval;

  58.  
  59. }

usb_hcd_add 干了哪些事:

    1、hcd_buffer_create(hcd) 

    2、usb_register_bus(&hcd->self) ,将 usb_hcd.usb_bus 注册到全局链表 usb_bus_list

    3、为根 hub 分配一个 usb_device 结构(内核中,所有的真实的usb设备(Hub,鼠标...)都用usb_device结构来描述)

    4、注册根 Hub 的 usb_device 结构到 usb_bus_type

    弄了半天,神神秘秘的USB主机控制器也只不过是分配了一个 usb_hcd 结构体,为它的 根hub 分配了一个usb_device 结构体,注册到 usb_bus_type 罢了,后边是 根Hub 的注册和设备枚举过程了。

 
  1. struct usb_device *usb_alloc_dev(struct usb_device *parent,

  2. struct usb_bus *bus, unsigned port1)

  3. {

  4. struct usb_device *dev;

  5. struct usb_hcd *usb_hcd = container_of(bus, struct usb_hcd, self);

  6. unsigned root_hub = 0;

  7. /* 分配一个 usb_device */

  8. dev = kzalloc(sizeof(*dev), GFP_KERNEL);

  9.  
  10. device_initialize(&dev->dev);

  11. /* usb_bus_type */

  12. dev->dev.bus = &usb_bus_type;

  13. /* 属性文件 */

  14. dev->dev.type = &usb_device_type;

  15. dev->dev.groups = usb_device_groups;

  16. dev->dev.dma_mask = bus->controller->dma_mask;

  17. set_dev_node(&dev->dev, dev_to_node(bus->controller));

  18. dev->state = USB_STATE_ATTACHED;

  19. atomic_set(&dev->urbnum, 0);

  20.  
  21. INIT_LIST_HEAD(&dev->ep0.urb_list);

  22. dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;

  23. dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;

  24. /* ep0 maxpacket comes later, from device descriptor */

  25. usb_enable_endpoint(dev, &dev->ep0, false);

  26. dev->can_submit = 1;

  27.  
  28. /* 如果是根Hub */

  29. if (unlikely(!parent)) {

  30. ...

  31. } else {

  32. ...

  33. }

  34.  
  35. <span style="white-space:pre"> </span>...

  36. }

  37. return dev;

  38. }

注意一下几点:

    1、dev->dev.bus = &usb_bus_type 这里出现了一条“总线模型”中的总线,注意和 usb_bus 完全没关系。相当于hub 、鼠标等 usb 设备是注册到 usb_bus_type 的,前面我们说的控制器的驱动是注册到 platform_bus_type 的。

    2、dev->dev.type = &usb_device_type ;后边Match函数中会用到

    3、dev->state = USB_STATE_ATTACHED; 根Hub是和控制器连在一起的,必然已经连接上了

      ATTACHED :表示设备已经连接到 hub 接口上了。

      Powered      :表示加电状态

      Default         :表示默认状态,在powered状态之后,设备必须受到一个复位信号并成功复位后,才能使用默认地址回应主机发过来的设备描述符的请求。

      Address        :表示主机分配了一个唯一的地址给设备。

      Configured   :表示设备已经被主机配置过了,此时,主机可以使用设备提供的所有功能。

      Supended    :表示挂起状态,设备在指定的时间内没有传输,就要进入挂起状态。
    4、dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT ,我们说一个 usb 设备有多个配置,每个配置又有多个接口,每个接口有多个 端点。但是端点 0 比较特殊,它是整个 usb 设备共享的,因此它的表述符直接在 usb_device中。

    5、dev->bus = bus ,根 Hub 连接到 控制器总线。

 
  1. static int register_root_hub(struct usb_hcd *hcd)

  2. {

  3. struct device *parent_dev = hcd->self.controller;

  4. struct usb_device *usb_dev = hcd->self.root_hub;

  5. const int devnum = 1;

  6. int retval;

  7.  
  8. /* 设备地址 */

  9. usb_dev->devnum = devnum;

  10. usb_dev->bus->devnum_next = devnum + 1;

  11. memset (&usb_dev->bus->devmap.devicemap, 0,

  12. sizeof usb_dev->bus->devmap.devicemap);

  13. set_bit (devnum, usb_dev->bus->devmap.devicemap);

  14. usb_set_device_state(usb_dev, USB_STATE_ADDRESS);

  15.  
  16. mutex_lock(&usb_bus_list_lock);

  17.  
  18. usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);

  19.  
  20. /* 获得设备描述符 */

  21. retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);

  22.  
  23. /* 进一步设置,然后 add_device */

  24. retval = usb_new_device (usb_dev);

  25.  
  26. return retval;

  27. }

    1、usb_dev->devnum = 1 ;根 Hub 的地址为1 ,usb_dev->bus->devmap.devicemap ,表示哪些设备地址被占用了,以及这个 hub 一共支持多少设备。

    2、usb_set_device_state(usb_dev, USB_STATE_ADDRESS); 变更状态

    3、usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE); 获得设备描述符,保存在usb_dev.descriptor 中。

    4、usb_new_device 进一步设置(获得配置、端点描述符等),将 usb_device 注册到 usb_bus_type 。

 
  1. int usb_get_device_descriptor(struct usb_device *dev, unsigned int size)

  2. {

  3. struct usb_device_descriptor *desc;

  4. int ret;

  5.  
  6. if (size > sizeof(*desc))

  7. return -EINVAL;

  8. desc = kmalloc(sizeof(*desc), GFP_NOIO);

  9. if (!desc)

  10. return -ENOMEM;

  11.  
  12. ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size);

  13. if (ret >= 0)

  14. memcpy(&dev->descriptor, desc, size);

  15. kfree(desc);

  16. return ret;

  17. }

 
  1. int usb_get_descriptor(struct usb_device *dev, unsigned char type,

  2. unsigned char index, void *buf, int size)

  3. {

  4. int i;

  5. int result;

  6.  
  7. memset(buf, 0, size); /* Make sure we parse really received data */

  8.  
  9. for (i = 0; i < 3; ++i) {

  10. /* retry on length 0 or error; some devices are flakey */

  11. result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),

  12. USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,

  13. (type << 8) + index, 0, buf, size,

  14. USB_CTRL_GET_TIMEOUT);

  15. if (result <= 0 && result != -ETIMEDOUT)

  16. continue;

  17. if (result > 1 && ((u8 *)buf)[1] != type) {

  18. result = -ENODATA;

  19. continue;

  20. }

  21. break;

  22. }

  23. return result;

  24. }

    注意,这里是将整个根Hub作为一个 device 注册到 usb_bus_type ,后边还会将Hub的接口注册进去

 
  1. int usb_new_device(struct usb_device *udev)

  2. {

  3. int err;

  4.  
  5. /* Increment the parent's count of unsuspended children */

  6. if (udev->parent)

  7. usb_autoresume_device(udev->parent);

  8.  
  9. usb_detect_quirks(udev); /* Determine quirks */

  10. err = usb_configure_device(udev); /* detect & probe dev/intfs */

  11.  
  12. /* export the usbdev device-node for libusb */

  13. udev->dev.devt = MKDEV(USB_DEVICE_MAJOR,

  14. (((udev->bus->busnum-1) * 128) + (udev->devnum-1)));

  15.  
  16. /* Tell the world! */

  17. announce_device(udev);

  18.  
  19. /* Register the device. The device driver is responsible

  20. * for configuring the device and invoking the add-device

  21. * notifier chain (used by usbfs and possibly others).

  22. */

  23. err = device_add(&udev->dev);

  24.  
  25. (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev);

  26. return err;

  27.  
  28. }

  29.  
 
  1. static int usb_configure_device(struct usb_device *udev)

  2. {

  3. usb_get_configuration(udev);

  4. }

 
  1. int usb_get_configuration(struct usb_device *dev)

  2. {

  3. struct device *ddev = &dev->dev;

  4. int ncfg = dev->descriptor.bNumConfigurations;

  5. int result = 0;

  6. unsigned int cfgno, length;

  7. unsigned char *buffer;

  8. unsigned char *bigbuffer;

  9. struct usb_config_descriptor *desc;

  10.  
  11. cfgno = 0;

  12.  
  13. if (ncfg > USB_MAXCONFIG) {

  14. dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG;

  15. }

  16.  
  17. length = ncfg * sizeof(struct usb_host_config);

  18. dev->config = kzalloc(length, GFP_KERNEL);

  19.  
  20. length = ncfg * sizeof(char *);

  21. dev->rawdescriptors = kzalloc(length, GFP_KERNEL);

  22.  
  23. buffer = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL);

  24.  
  25. desc = (struct usb_config_descriptor *)buffer;

  26.  
  27. result = 0;

  28. for (; cfgno < ncfg; cfgno++) {

  29. /* We grab just the first descriptor so we know how long the whole configuration is */

  30. result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, USB_DT_CONFIG_SIZE);

  31.  
  32. length = max((int) le16_to_cpu(desc->wTotalLength), USB_DT_CONFIG_SIZE);

  33.  
  34. /* Now that we know the length, get the whole thing */

  35. bigbuffer = kmalloc(length, GFP_KERNEL);

  36.  
  37. result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, length);

  38.  
  39. dev->rawdescriptors[cfgno] = bigbuffer;

  40. /* 解析配置描述符 */

  41. result = usb_parse_configuration(&dev->dev, cfgno, &dev->config[cfgno], bigbuffer, length);

  42. }

  43. result = 0;

  44.  
  45. return result;

  46. }

    也就是说,在将 usb_device 注册到 usb_bus_type 时,它所有的描述符信息都已经获取到了。

    整个控制器驱动一路走下来,最后 注册了一个根 Hub 的 usb_device 到 usb_bus_type 。有必要看一下usb_bus_type ,它的 match 函数,将注册进来的 device 和 接口分开处理。第一次注册的我们说是 device ,那么看看对应的 driver 是啥。

 
  1. struct bus_type usb_bus_type = {

  2. .name = "usb",

  3. .match = usb_device_match,

  4. .uevent = usb_uevent,

  5. };

 
  1. static int usb_device_match(struct device *dev, struct device_driver *drv)

  2. {

  3. /* return dev->type == &usb_device_type; */

  4. if (is_usb_device(dev)) {

  5.  
  6. /* return container_of(drv, struct usbdrv_wrap, driver)->for_devices; */

  7. if (!is_usb_device_driver(drv))

  8. return 0;

  9.  
  10. /* TODO: Add real matching code */

  11. return 1;

  12.  
  13. } else if (is_usb_interface(dev)) {

  14. ....

  15. }

  16.  
  17. return 0;

  18. }

    如果设备的 dev->type == &usb_device_type ,且 driver.for_devices == 1 ,直接匹配成功。匹配成功之后便会调用driver侧的 probe 函数了。

 
  1. struct usb_device_driver usb_generic_driver = {

  2. .name = "usb",

  3. .probe = generic_probe,

  4. .disconnect = generic_disconnect,

  5. #ifdef CONFIG_PM

  6. .suspend = generic_suspend,

  7. .resume = generic_resume,

  8. #endif

  9. .supports_autosuspend = 1,

  10. };

 
  1. static int generic_probe(struct usb_device *udev)

  2. {

  3. int err, c;

  4.  
  5. c = usb_choose_configuration(udev);

  6.  
  7. err = usb_set_configuration(udev, c);

  8.  
  9. /* USB device state == configured ... usable */

  10. usb_notify_add_device(udev);

  11.  
  12. return 0;

  13. }

 
  1. int usb_set_configuration(struct usb_device *dev, int configuration)

  2. {

  3. int i, ret;

  4. struct usb_host_config *cp = NULL;

  5. struct usb_interface **new_interfaces = NULL;

  6. int n, nintf;

  7.  
  8. if (dev->authorized == 0 || configuration == -1)

  9. configuration = 0;

  10. else {

  11. for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {

  12. if (dev->config[i].desc.bConfigurationValue ==

  13. configuration) {

  14. cp = &dev->config[i];

  15. break;

  16. }

  17. }

  18. }

  19.  
  20. n = nintf = 0;

  21. if (cp) {

  22. /* new_interfaces 是个指针数组,首先为它分配空间 */

  23. nintf = cp->desc.bNumInterfaces;

  24. new_interfaces = kmalloc(nintf * sizeof(*new_interfaces), GFP_KERNEL);

  25. /* 为它指向的接口分配空间 */

  26. for (; n < nintf; ++n) {

  27. new_interfaces[n] = kzalloc(sizeof(struct usb_interface), GFP_KERNEL);

  28. }

  29.  
  30. i = dev->bus_mA - cp->desc.bMaxPower * 2;

  31. }

  32.  
  33. /* Wake up the device so we can send it the Set-Config request */

  34. ret = usb_autoresume_device(dev);

  35.  
  36. if (cp)

  37. ret = usb_hcd_check_bandwidth(dev, cp, NULL);

  38. else

  39. ret = usb_hcd_check_bandwidth(dev, NULL, NULL);

  40.  
  41. /* if it's already configured, clear out old state first.

  42. * getting rid of old interfaces means unbinding their drivers.

  43. */

  44. if (dev->state != USB_STATE_ADDRESS)

  45. usb_disable_device(dev, 1); /* Skip ep0 */

  46.  
  47. /* Get rid of pending async Set-Config requests for this device */

  48. cancel_async_set_config(dev);

  49.  
  50. /* 设置配置 */

  51. ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),

  52. USB_REQ_SET_CONFIGURATION, 0, configuration, 0,

  53. NULL, 0, USB_CTRL_SET_TIMEOUT);

  54.  
  55. dev->actconfig = cp;

  56.  
  57. /* 变更状态 */

  58. usb_set_device_state(dev, USB_STATE_CONFIGURED);

  59.  
  60. /* 设置这个配置的所有接口 */

  61. for (i = 0; i < nintf; ++i) {

  62. struct usb_interface_cache *intfc;

  63. struct usb_interface *intf;

  64. struct usb_host_interface *alt;

  65.  
  66. cp->interface[i] = intf = new_interfaces[i];

  67. intfc = cp->intf_cache[i];

  68. intf->altsetting = intfc->altsetting;

  69. intf->num_altsetting = intfc->num_altsetting;

  70. intf->intf_assoc = find_iad(dev, cp, i);

  71. kref_get(&intfc->ref);

  72.  
  73. alt = usb_altnum_to_altsetting(intf, 0);

  74.  
  75. if (!alt)

  76. alt = &intf->altsetting[0];

  77.  
  78. intf->cur_altsetting = alt;

  79. usb_enable_interface(dev, intf, true);

  80. intf->dev.parent = &dev->dev;

  81. intf->dev.driver = NULL;

  82. intf->dev.bus = &usb_bus_type;

  83.  
  84. /* 注意这个,match时会区分 device 和 接口 */

  85. intf->dev.type = &usb_if_device_type;

  86. intf->dev.groups = usb_interface_groups;

  87. intf->dev.dma_mask = dev->dev.dma_mask;

  88. INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);

  89. device_initialize(&intf->dev);

  90. mark_quiesced(intf);

  91. dev_set_name(&intf->dev, "%d-%s:%d.%d",

  92. dev->bus->busnum, dev->devpath,

  93. configuration, alt->desc.bInterfaceNumber);

  94. }

  95. kfree(new_interfaces);

  96.  
  97. if (cp->string == NULL &&

  98. !(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))

  99. cp->string = usb_cache_string(dev, cp->desc.iConfiguration);

  100.  
  101. for (i = 0; i < nintf; ++i) {

  102. struct usb_interface *intf = cp->interface[i];

  103.  
  104. /* 注册到 usb_bus_type */

  105. ret = device_add(&intf->dev);

  106. create_intf_ep_devs(intf);

  107. }

  108.  
  109. usb_autosuspend_device(dev);

  110. return 0;

  111. }

 
  1. static int usb_device_match(struct device *dev, struct device_driver *drv)

  2. {

  3. /* devices and interfaces are handled separately */

  4. if (is_usb_device(dev)) {

  5. <span style="white-space:pre"> </span>...

  6. } else if (is_usb_interface(dev)) {

  7. struct usb_interface *intf;

  8. struct usb_driver *usb_drv;

  9. const struct usb_device_id *id;

  10.  
  11. /* device drivers never match interfaces */

  12. if (is_usb_device_driver(drv))

  13. return 0;

  14.  
  15. intf = to_usb_interface(dev);

  16. usb_drv = to_usb_driver(drv);

  17.  
  18. id = usb_match_id(intf, usb_drv->id_table);

  19. if (id)

  20. return 1;

  21.  
  22. id = usb_match_dynamic_id(intf, usb_drv);

  23. if (id)

  24. return 1;

  25. }

  26.  
  27. return 0;

  28. }

    第一次注册进来的是 devies,在通用的driver 的 probe 函数,将该设备的所有接口信息都读取出来并设置再注册到 usb_bus_type 中,也就是说在match函数中,会走下边这个分支,根据 dirver 的 id_table 来匹配,根 Hub 的接口自然是与 hub_driver 进行匹配。

 
  1. static struct usb_driver hub_driver = {

  2. .name = "hub",

  3. .probe = hub_probe,

  4. .disconnect = hub_disconnect,

  5. .suspend = hub_suspend,

  6. .resume = hub_resume,

  7. .reset_resume = hub_reset_resume,

  8. .pre_reset = hub_pre_reset,

  9. .post_reset = hub_post_reset,

  10. .ioctl = hub_ioctl,

  11. .id_table = hub_id_table,

  12. .supports_autosuspend = 1,

  13. };

 
  1. int usb_hub_init(void)

  2. {

  3. if (usb_register(&hub_driver) < 0) {

  4. ...

  5. }

  6. /* 创建内核线程,子进程将从 hub_thread 开始,名字叫 khubd */

  7. khubd_task = kthread_run(hub_thread, NULL, "khubd");

  8. }

    分析过设备模型的都知道,匹配成功后调用的是usb_driver.driver.probe函数,然而这里并没有,而且usb_bus_type中也没有 probe 函数,那么有可能是在driver的注册过程中动了哪些手脚。

 
  1. static inline int usb_register(struct usb_driver *driver)

  2. {

  3. return usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);

  4. }

 
  1. int usb_register_driver(struct usb_driver *new_driver, struct module *owner,

  2. const char *mod_name)

  3. {

  4. int retval = 0;

  5.  
  6. if (usb_disabled())

  7. return -ENODEV;

  8.  
  9. new_driver->drvwrap.for_devices = 0;

  10. new_driver->drvwrap.driver.name = (char *) new_driver->name;

  11. new_driver->drvwrap.driver.bus = &usb_bus_type;

  12. new_driver->drvwrap.driver.probe = usb_probe_interface;

  13. new_driver->drvwrap.driver.remove = usb_unbind_interface;

  14. new_driver->drvwrap.driver.owner = owner;

  15. new_driver->drvwrap.driver.mod_name = mod_name;

  16. spin_lock_init(&new_driver->dynids.lock);

  17. INIT_LIST_HEAD(&new_driver->dynids.list);

  18.  
  19. retval = driver_register(&new_driver->drvwrap.driver);

  20.  
  21. if (!retval) {

  22. pr_info("%s: registered new interface driver %s\n",

  23. usbcore_name, new_driver->name);

  24. usbfs_update_special();

  25. usb_create_newid_file(new_driver);

  26. } else {

  27. printk(KERN_ERR "%s: error %d registering interface "

  28. " driver %s\n",

  29. usbcore_name, retval, new_driver->name);

  30. }

  31.  
  32. return retval;

  33. }

    这里注册到 usb_bus_type 的是 usb_driver.drvwrap.driver ,那么匹配成功后调用的自然是 usb_probe_interface

 
  1. static int usb_probe_interface(struct device *dev)

  2. {

  3. struct usb_driver *driver = to_usb_driver(dev->driver);

  4. struct usb_interface *intf = to_usb_interface(dev);

  5. struct usb_device *udev = interface_to_usbdev(intf);

  6. const struct usb_device_id *id;

  7. int error = -ENODEV;

  8.  
  9. dev_dbg(dev, "%s\n", __func__);

  10.  
  11. intf->needs_binding = 0;

  12.  
  13. id = usb_match_id(intf, driver->id_table);

  14. if (!id)

  15. id = usb_match_dynamic_id(intf, driver);

  16. if (id) {

  17. dev_dbg(dev, "%s - got id\n", __func__);

  18.  
  19. error = usb_autoresume_device(udev);

  20. mark_active(intf);

  21. intf->condition = USB_INTERFACE_BINDING;

  22.  
  23. atomic_set(&intf->pm_usage_cnt, !driver->supports_autosuspend);

  24.  
  25. if (intf->needs_altsetting0) {

  26. error = usb_set_interface(udev, intf->altsetting[0].

  27. desc.bInterfaceNumber, 0);

  28.  
  29. intf->needs_altsetting0 = 0;

  30. }

  31. <span style="white-space:pre"> </span>/* 看这里 */

  32. error = driver->probe(intf, id);

  33.  
  34. intf->condition = USB_INTERFACE_BOUND;

  35. usb_autosuspend_device(udev);

  36. }

  37.  
  38. return error;

  39. }

    获取到 usb_device 的接口 usb_interface 以及 usb_device_id ,然后 driver->probe(intf, id) 调用到 usb_driver.probe 函数。传递进来的参数非常重要~,尤其是第一个 ---接口。再看 probe 函数之前,还有一点需要先看一下。

 
  1. int usb_hub_init(void)

  2. {

  3. if (usb_register(&hub_driver) < 0) {

  4. ...

  5. }

  6. /* 创建内核线程,子进程将从 hub_thread 开始,名字叫 khubd */

  7. khubd_task = kthread_run(hub_thread, NULL, "khubd");

  8. }

 
  1. static int hub_thread(void *__unused)

  2. {

  3. /* khubd needs to be freezable to avoid intefering with USB-PERSIST

  4. * port handover. Otherwise it might see that a full-speed device

  5. * was gone before the EHCI controller had handed its port over to

  6. * the companion full-speed controller.

  7. */

  8. set_freezable();

  9.  
  10. do {

  11. hub_events();

  12. /* wait_event_interruptible(khubd_wait, ... */

  13. wait_event_freezable(khubd_wait,

  14. !list_empty(&hub_event_list) ||

  15. kthread_should_stop());

  16. } while (!kthread_should_stop() || !list_empty(&hub_event_list));

  17.  
  18. pr_debug("%s: khubd exiting\n", usbcore_name);

  19. return 0;

  20. }

    这个内核线程里干两件事,第一,hub_events(),第二休眠,等待唤醒。

 
  1. static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)

  2. {

  3. struct usb_host_interface *desc;

  4. struct usb_endpoint_descriptor *endpoint;

  5. struct usb_device *hdev;

  6. struct usb_hub *hub;

  7.  
  8. desc = intf->cur_altsetting;

  9. hdev = interface_to_usbdev(intf);

  10.  
  11. /* Hub 的子类就是0,即desc->desc 这个interface 描述符里边的bInterfaceSubClass就应该是0 */

  12. if ((desc->desc.bInterfaceSubClass != 0) &&

  13. (desc->desc.bInterfaceSubClass != 1)) {

  14. ...

  15. }

  16.  
  17. /* spec 规定了Hub 只有一个端点(除去端点0)也就是中断端点 */

  18. if (desc->desc.bNumEndpoints != 1)

  19. goto descriptor_error;

  20.  
  21. endpoint = &desc->endpoint[0].desc;

  22.  
  23. /* 判断这个端点是否是中断端点 */

  24. if (!usb_endpoint_is_int_in(endpoint))

  25. goto descriptor_error;

  26. /* 分配一个usb_hub */

  27. hub = kzalloc(sizeof(*hub), GFP_KERNEL);

  28.  
  29. kref_init(&hub->kref);

  30. INIT_LIST_HEAD(&hub->event_list);

  31.  
  32. hub->intfdev = &intf->dev; //hub device

  33. hub->hdev = hdev; //hub usb_device

  34.  
  35. INIT_DELAYED_WORK(&hub->leds, led_work);

  36. INIT_DELAYED_WORK(&hub->init_work, NULL);

  37. usb_get_intf(intf);

  38.  
  39. /* intf->dev = hub */

  40. usb_set_intfdata (intf, hub);

  41.  
  42. intf->needs_remote_wakeup = 1;

  43.  
  44. if (hdev->speed == USB_SPEED_HIGH)

  45. highspeed_hubs++;

  46.  
  47. if (hub_configure(hub, endpoint) >= 0)

  48. return 0;

  49.  
  50. }

 
  1. static int hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor *endpoint)

  2. {

  3. struct usb_hcd *hcd;

  4. struct usb_device *hdev = hub->hdev;

  5. struct device *hub_dev = hub->intfdev;

  6. u16 hubstatus, hubchange;

  7. u16 wHubCharacteristics;

  8. unsigned int pipe;

  9. int maxp, ret;

  10. char *message = "out of memory";

  11.  
  12. /* 内存分配 */

  13. hub->buffer = usb_buffer_alloc(hdev, sizeof(*hub->buffer), GFP_KERNEL,

  14. &hub->buffer_dma);

  15. hub->status = kmalloc(sizeof(*hub->status), GFP_KERNEL);

  16. mutex_init(&hub->status_mutex);

  17. hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);

  18.  
  19. /* 获得 hub 描述符 */

  20. ret = get_hub_descriptor(hdev, hub->descriptor,

  21. sizeof(*hub->descriptor));

  22.  
  23. }

  24. /* hub 支持的最大下行端口 */

  25. hdev->maxchild = hub->descriptor->bNbrPorts;

  26.  
  27. hub->port_owners = kzalloc(hdev->maxchild * sizeof(void *), GFP_KERNEL);

  28.  
  29. wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics);

  30.  
  31. if (wHubCharacteristics & HUB_CHAR_COMPOUND) {

  32. /* 复合设备 */

  33. } else

  34. dev_dbg(hub_dev, "standalone hub\n");

  35.  
  36. switch (wHubCharacteristics & HUB_CHAR_LPSM) {

  37. /* 电源切换方式 */

  38. }

  39.  
  40. switch (wHubCharacteristics & HUB_CHAR_OCPM) {

  41. /* 过流保护模式 */

  42. }

  43.  
  44. spin_lock_init (&hub->tt.lock);

  45. INIT_LIST_HEAD (&hub->tt.clear_list);

  46. INIT_WORK(&hub->tt.clear_work, hub_tt_work);

  47.  
  48. switch (hdev->descriptor.bDeviceProtocol) {

  49. /* 低速全速设备掠过 */

  50. }

  51.  
  52. /* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */

  53. switch (wHubCharacteristics & HUB_CHAR_TTTT) {

  54. /* 指定 hub->tt.think_time = 666 * n; n根据设备速度不同而不同*/

  55. }

  56.  
  57. /* 是否支持 hub 上的指示灯 */

  58. if (wHubCharacteristics & HUB_CHAR_PORTIND) {

  59. hub->has_indicators = 1;

  60. dev_dbg(hub_dev, "Port indicators are supported\n");

  61. }

  62. /* 请求设备状态 */

  63. ret = usb_get_status(hdev, USB_RECIP_DEVICE, 0, &hubstatus);

  64.  
  65. le16_to_cpus(&hubstatus);

  66.  
  67. /* hub 的端口电流 */

  68. if (hdev == hdev->bus->root_hub) { //根Hub

  69. ...

  70. }

  71.  
  72.  
  73. /* Update the HCD's internal representation of this hub before khubd

  74. * starts getting port status changes for devices under the hub.

  75. */

  76. hcd = bus_to_hcd(hdev->bus);

  77. if (hcd->driver->update_hub_device) {

  78. ret = hcd->driver->update_hub_device(hcd, hdev,

  79. &hub->tt, GFP_KERNEL);

  80.  
  81. }

  82.  
  83. ret = hub_hub_status(hub, &hubstatus, &hubchange);

  84.  
  85. /* 获得主机和 Hub 端点的管道 */

  86. pipe = usb_rcvintpipe(hdev, endpoint->bEndpointAddress);

  87. maxp = usb_maxpacket(hdev, pipe, usb_pipeout(pipe));

  88.  
  89. if (maxp > sizeof(*hub->buffer))

  90. maxp = sizeof(*hub->buffer);

  91.  
  92. /* 分配一个urb */

  93. hub->urb = usb_alloc_urb(0, GFP_KERNEL);

  94. /* 填充Urb */

  95. usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq,

  96. hub, endpoint->bInterval);

  97. hub->urb->transfer_dma = hub->buffer_dma;

  98. hub->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

  99.  
  100. /* maybe cycle the hub leds */

  101. if (hub->has_indicators && blinkenlights)

  102. hub->indicator [0] = INDICATOR_CYCLE;

  103.  
  104. //tatus = usb_submit_urb(hub->urb, GFP_NOIO);

  105. //kick_khubd(hub) -> wake_up(&khubd_wait);

  106. hub_activate(hub, HUB_INIT);

  107. return 0;

  108.  
  109. }

    填充一个 urb ,检测 hub 端口状态,如果有状态发生改变,则会调用 hub_irq 

 
  1. static void hub_irq(struct urb *urb)

  2. {

  3. struct usb_hub *hub = urb->context;

  4. int status = urb->status;

  5. unsigned i;

  6. unsigned long bits;

  7.  
  8. switch (status) {

  9. ....

  10.  
  11. /* let khubd handle things */

  12. case 0: /* we got data: port status changed */

  13. bits = 0;

  14. for (i = 0; i < urb->actual_length; ++i)

  15. bits |= ((unsigned long) ((*hub->buffer)[i]))

  16. << (i*8);

  17. hub->event_bits[0] = bits;

  18. break;

  19. }

  20.  
  21. hub->nerrors = 0;

  22.  
  23. /* Something happened, let khubd figure it out */

  24. kick_khubd(hub);

  25.  
  26. resubmit:

  27. if (hub->quiescing)

  28. return;

  29.  
  30. if ((status = usb_submit_urb (hub->urb, GFP_ATOMIC)) != 0

  31. && status != -ENODEV && status != -EPERM)

  32. dev_err (hub->intfdev, "resubmit --> %d\n", status);

  33. }

    如果哪一位端口发生了变化,标记在 Hub->event_bits[0]中,然后唤醒线程,hub_event 被调用。再次提交 urb

 
  1. static void hub_events(void)

  2. {

  3. struct list_head *tmp;

  4. struct usb_device *hdev;

  5. struct usb_interface *intf;

  6. struct usb_hub *hub;

  7. struct device *hub_dev;

  8. u16 hubstatus;

  9. u16 hubchange;

  10. u16 portstatus;

  11. u16 portchange;

  12. int i, ret;

  13. int connect_change;

  14.  
  15. while (1) {

  16.  
  17. /* Grab the first entry at the beginning of the list */

  18. spin_lock_irq(&hub_event_lock);

  19.  
  20. tmp = hub_event_list.next;

  21. list_del_init(tmp);

  22.  
  23. hub = list_entry(tmp, struct usb_hub, event_list);

  24. kref_get(&hub->kref);

  25. spin_unlock_irq(&hub_event_lock);

  26.  
  27. hdev = hub->hdev;

  28. hub_dev = hub->intfdev;

  29. intf = to_usb_interface(hub_dev);

  30.  
  31. /* Lock the device, then check to see if we were

  32. * disconnected while waiting for the lock to succeed. */

  33. usb_lock_device(hdev);

  34.  
  35. /* Autoresume */

  36. ret = usb_autopm_get_interface(intf);

  37.  
  38. /* deal with port status changes */

  39. for (i = 1; i <= hub->descriptor->bNbrPorts; i++) {

  40. if (test_bit(i, hub->busy_bits))

  41. continue;

  42.  
  43. connect_change = test_bit(i, hub->change_bits);

  44. /* 第i位为0返回0 否则返回1,如果端口发生变化,返回1 */

  45. if (!test_and_clear_bit(i, hub->event_bits) &&

  46. !connect_change)

  47. continue;

  48. /* 程序运行到这,说明第i个端口发生了变化 */

  49. ret = hub_port_status(hub, i, &portstatus, &portchange);

  50.  
  51. if (portchange & USB_PORT_STAT_C_CONNECTION) {

  52. clear_port_feature(hdev, i, USB_PORT_FEAT_C_CONNECTION);

  53. connect_change = 1;

  54. }

  55.  
  56. if (portchange & USB_PORT_STAT_C_ENABLE) {

  57. ...

  58. }

  59.  
  60. if (portchange & USB_PORT_STAT_C_SUSPEND) {

  61. ...

  62. }

  63.  
  64. if (portchange & USB_PORT_STAT_C_OVERCURRENT) {

  65. ...

  66. }

  67.  
  68. if (portchange & USB_PORT_STAT_C_RESET) {

  69. ...

  70. }

  71.  
  72. if (connect_change)

  73. hub_port_connect_change(hub, i, portstatus, portchange);

  74. } /* end for i */

  75. ...

  76. }

 
  1. static void hub_port_connect_change(struct usb_hub *hub, int port1,

  2. u16 portstatus, u16 portchange)

  3. {

  4. struct usb_device *hdev = hub->hdev;

  5. struct device *hub_dev = hub->intfdev;

  6. struct usb_hcd *hcd = bus_to_hcd(hdev->bus);

  7. unsigned wHubCharacteristics =

  8. le16_to_cpu(hub->descriptor->wHubCharacteristics);

  9. struct usb_device *udev;

  10. int status, i;

  11.  
  12. for (i = 0; i < SET_CONFIG_TRIES; i++) {

  13.  
  14. /* 分配一个 usb_device */

  15. udev = usb_alloc_dev(hdev, hdev->bus, port1);

  16.  
  17. /* 设置它的状态为 加电的 */

  18. usb_set_device_state(udev, USB_STATE_POWERED);

  19. udev->bus_mA = hub->mA_per_port;

  20. udev->level = hdev->level + 1;

  21. udev->wusb = hub_is_wusb(hub);

  22. udev->speed = USB_SPEED_UNKNOWN;

  23.  
  24. /* 分配一个地址 devnum = find_next_zero_bit(bus->devmap.devicemap, 128, bus->devnum_next); */

  25. choose_address(udev);

  26.  
  27. /* 复位 获取描述符 */

  28. status = hub_port_init(hub, udev, port1, i);

  29.  
  30. status = 0;

  31.  
  32. /* Run it through the hoops (find a driver, etc) */

  33. if (!status) {

  34. status = usb_new_device(udev);

  35. }

  36.  
  37. status = hub_power_remaining(hub);

  38.  
  39. return;

  40. }

 
  1. static int hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,

  2. int retry_counter)

  3. {

  4. static DEFINE_MUTEX(usb_address0_mutex);

  5.  
  6. struct usb_device *hdev = hub->hdev;

  7. struct usb_hcd *hcd = bus_to_hcd(hdev->bus);

  8. int i, j, retval;

  9. unsigned delay = HUB_SHORT_RESET_TIME;

  10. enum usb_device_speed oldspeed = udev->speed;

  11. char *speed, *type;

  12. int devnum = udev->devnum;

  13.  
  14. mutex_lock(&usb_address0_mutex);

  15.  
  16. retval = hub_port_reset(hub, port1, udev, delay);

  17.  
  18. oldspeed = udev->speed;

  19.  
  20. /* 根据传输速度设置端点0的最大包大小 */

  21. switch (udev->speed) {

  22. case USB_SPEED_SUPER:

  23. case USB_SPEED_VARIABLE: /* fixed at 512 */

  24. udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);

  25. break;

  26. case USB_SPEED_HIGH: /* fixed at 64 */

  27. udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);

  28. break;

  29. case USB_SPEED_FULL: /* 8, 16, 32, or 64 */

  30. udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);

  31. break;

  32. case USB_SPEED_LOW: /* fixed at 8 */

  33. udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8);

  34. break;

  35. default:

  36. goto fail;

  37. }

  38.  
  39. type = "";

  40. switch (udev->speed) {

  41. case USB_SPEED_LOW: speed = "low"; break;

  42. case USB_SPEED_FULL: speed = "full"; break;

  43. case USB_SPEED_HIGH: speed = "high"; break;

  44. case USB_SPEED_SUPER:

  45. speed = "super";

  46. break;

  47. case USB_SPEED_VARIABLE:

  48. speed = "variable";

  49. type = "Wireless ";

  50. break;

  51. default: speed = "?"; break;

  52. }

  53.  
  54. for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) {

  55.  
  56. if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) {

  57. ...

  58. }

  59.  
  60. if (udev->wusb == 0) {

  61. for (j = 0; j < SET_ADDRESS_TRIES; ++j) {

  62.  
  63. /* 将分配的地址告诉设备 ,并设置设备状态为 USB_STATE_ADDRESS */

  64. retval = hub_set_address(udev, devnum);

  65.  
  66. msleep(200);

  67. }

  68.  
  69. if (udev->speed == USB_SPEED_SUPER) {

  70. devnum = udev->devnum;

  71. }

  72.  
  73. msleep(10);

  74. if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3))

  75. break;

  76. }

  77. /* 不知道一次能获取多少,但至少能获取8 */

  78. retval = usb_get_device_descriptor(udev, 8);

  79. if (retval < 8) {

  80. ...

  81. } else {

  82. retval = 0;

  83. break;

  84. }

  85. }

  86.  
  87. if (udev->descriptor.bMaxPacketSize0 == 0xff ||

  88. udev->speed == USB_SPEED_SUPER)

  89. i = 512;

  90. else

  91. i = udev->descriptor.bMaxPacketSize0;

  92. if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) {

  93.  
  94. udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);

  95. usb_ep0_reinit(udev);

  96. }

  97. /* 重新获取全部描述符 */

  98. retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);

  99.  
  100. retval = 0;

  101.  
  102. mutex_unlock(&usb_address0_mutex);

  103. return retval;

  104. }

    在 Hub_event 中,会调用 对于状态变化的端口调用 hub_port_status 来检测Hub端口的具体状态,然后调用 hub_port_connect_change 

    hub_port_connect_change
        udev = usb_alloc_dev(hdev, hdev->bus, port1);
            dev->dev.bus = &usb_bus_type;
        choose_address(udev); // 给新设备分配编号(地址)
        hub_port_init   // usb 1-1: new full speed USB device using s3c2410-ohci and address 3
            hub_set_address  // 把编号(地址)告诉USB设备
            usb_get_device_descriptor(udev, 8); // 获取设备描述符
            retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);
            usb_new_device(udev)   
                err = usb_get_configuration(udev); // 把所有的描述符都读出来,并解析
                usb_parse_configuration
                device_add  // 把device放入usb_bus_type的dev链表, 
                    // 从usb_bus_type的driver链表里取出usb_driver,
                    // 把usb_interface和usb_driver的id_table比较
                    // 如果能匹配,调用usb_driver的probe

    显然,从 usb_alloc_dev 开始,重复了如同根 Hub 作为一个 device 注册进内核时的流程。如此循环下去,就能枚举注册所有的 usb 设备。




 

猜你喜欢

转载自blog.csdn.net/yangming2466/article/details/83218729