当前位置:   article > 正文

linux USB驱动分析(四)USB hub集线器驱动分析_usb hub linux驱动

usb hub linux驱动

关键词:linux、驱动、usb、usb hub、集线器、热插拔

       每当有设备连接到USB接口时,USB总线在查询hub状态信息的时候会触发hub的中断服务程序hub_irq, 在该函数中置位event_bits,运行工作队列。进入hub_event函数,该函数用来处理端口变化的事件。然后通过一个for循环来检测每个端口的状态信息。利用usb_port_status获取端口信息,如果发生变化就调用hub_port_connect_change函数来配置端口等。

usb设备插入hub的流程

usb hub热插拔

参见文档<<Linux那些事儿之我是USB Core.pdf>>。

 hub_configure 调用了 usb_fill_int_urb()函数,并且把 hub_irq 作为一个参数传递了进去,最终把 urb->complete 赋值为 hub_irq。然后,主机控制器会定期询问 hub,每当 hub端口上有一个设备插入或者拔除时它就会通过USB中断传输的方式向主机控制器打小报告。具体来说,从硬件的角度看,就是Hub 会向主机控制器返回一些信息,或者说 Data,这个 Data 被称作“ Hub and Port Status Change Bitmap”,而从软件角度来看, 主机控制器的驱动程序接下来会在处理好这个过程的 urb 之后, 调用该 urb 的 complete函数,对于 Hub 来说,这个函数就是 hub_irq()。

以USB2.0主机控制器ehci 为例,根集线器和子集线器的驱动 static struct usb_driver hub_driver 的探测函数 hub_probe() 会创建一个中断传输的 urb 并通过函数usb_hcd_submit_urb()->ehci_urb_enqueue() 提交给主机控制器 :

  1. int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)->
  2. INIT_WORK(&hub->events, hub_event); //用于处理hub的事件INIT_WORK(&hub->events, hub_event);
  3. hub_configure(hub, endpoint)->
  4. usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq,hub, endpoint->bInterval)->
  5. hub_activate(hub, HUB_INIT)->
  6. usb_submit_urb(hub->urb, GFP_NOIO)-> //提交urb,等执行完成就会回调hub_irq
  7. return usb_hcd_submit_urb(urb, mem_flags)-> //将 hub->urb 提交给主机控制器,urb 传输完成时会调用函数 hub_irq
  8. if (is_root_hub(urb->dev)) //是否为根集线器
  9. {
  10. status = rh_urb_enqueue(hcd, urb)->
  11. return rh_queue_status (hcd, urb);
  12. }
  13. else //子集线器或其它 USB 设备
  14. {
  15. status = map_urb_for_dma(hcd, urb, mem_flags);
  16. hcd->driver->urb_enqueue(hcd, urb, mem_flags);
  17. //对于 ehci 主机控制器 hcd->driver->urb_enqueue = struct hc_driver ehci_hc_driver.urb_enqueue =ehci_urb_enqueue
  18. static int ehci_urb_enqueue ();
  19. }

具体过程如下:

  1. int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)->
  2. INIT_WORK(&hub->events, hub_event); //用于处理hub的事件INIT_WORK(&hub->events, hub_event);
  3. hub_configure(hub, endpoint)->
  4. usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq,hub, endpoint->bInterval)->
  5. urb->dev = dev;
  6. urb->pipe = pipe;
  7. urb->transfer_buffer = transfer_buffer;
  8. urb->transfer_buffer_length = buffer_length;
  9. urb->complete = complete_fn = hub_irq;
  10. urb->context = context;
  11. //高速USB设备USB_SPEED_HIGH对应USB2.0协议
  12. if (dev->speed == USB_SPEED_HIGH || dev->speed == USB_SPEED_SUPER)
  13. {
  14. /* make sure interval is within allowed range */
  15. interval = clamp(interval, 1, 16); //高速USB设备的中断传输的时间间隔限制为 2^16 微帧,一微帧=1ms/8=0.125ms
  16. urb->interval = 1 << (interval - 1);
  17. } else {
  18. urb->interval = interval;
  19. }
  20. urb->start_frame = -1;
  21. hub_activate(hub, HUB_INIT)->
  22. usb_submit_urb(hub->urb, GFP_NOIO)-> //提交urb,等执行完成就会回调hub_irq
  23. struct usb_host_endpoint *ep = usb_pipe_endpoint(dev, urb->pipe);
  24. switch (xfertype) {
  25. case USB_ENDPOINT_XFER_ISOC:
  26. case USB_ENDPOINT_XFER_INT:
  27. /* too big? */
  28. switch (dev->speed) {
  29. case USB_SPEED_HIGH: //对应 USB2.0协议 /* units are microframes:单位是微帧,即 1ms/8 = 0.125ms */
  30. /* NOTE usb handles 2^15 = 32768*/
  31. if (urb->interval > (1024 * 8))
  32. urb->interval = 1024 * 8;
  33. max = 1024 * 8;
  34. break;
  35. case USB_SPEED_FULL: /* units are frames/msec :单位是 ms */
  36. case USB_SPEED_LOW:
  37. if (xfertype == USB_ENDPOINT_XFER_INT) {
  38. if (urb->interval > 255)
  39. return -EINVAL;
  40. /* NOTE ohci only handles up to 32 */
  41. max = 128;
  42. } else {
  43. if (urb->interval > 1024)
  44. urb->interval = 1024;
  45. /* NOTE usb and ohci handle up to 2^15 */
  46. max = 1024;
  47. }
  48. break;
  49. default:
  50. return -EINVAL;
  51. }
  52. if (dev->speed != USB_SPEED_WIRELESS) {
  53. /* Round down to a power of 2, no more than max */
  54. urb->interval = min(max, 1 << ilog2(urb->interval));
  55. }
  56. }
  57. return usb_hcd_submit_urb(urb, mem_flags)->
  58. if (is_root_hub(urb->dev)) //是否为根集线器
  59. {
  60. status = rh_urb_enqueue(hcd, urb)->
  61. return rh_queue_status (hcd, urb);
  62. }
  63. else //子集线器或其它 USB 设备
  64. {
  65. status = map_urb_for_dma(hcd, urb, mem_flags);
  66. hcd->driver->urb_enqueue(hcd, urb, mem_flags);
  67. //对于 ehci 主机控制器 hcd->driver->urb_enqueue = struct hc_driver ehci_hc_driver.urb_enqueue =ehci_urb_enqueue
  68. static int ehci_urb_enqueue ()->
  69. switch (usb_pipetype (urb->pipe))
  70. {
  71. case PIPE_INTERRUPT: //中断传输
  72. qh_urb_transaction (ehci, urb, &qtd_list, mem_flags)->
  73. struct ehci_qtd *qtd = ehci_qtd_alloc (ehci, flags);
  74. list_add_tail (&qtd->qtd_list, head); //加入到主机控制器的相关链表
  75. return intr_submit(ehci, urb, &qtd_list, mem_flags)->
  76. epnum = urb->ep->desc.bEndpointAddress;
  77. usb_hcd_link_urb_to_ep(ehci_to_hcd(ehci), urb);
  78. qh = qh_append_tds(ehci, urb, &empty, epnum, &urb->ep->hcpriv);
  79. qh_schedule (ehci, qh);
  80. qh_append_tds(ehci, urb, qtd_list, epnum, &urb->ep->hcpriv);
  81. }
  82. }

如果将函数hub_configure(hub, endpoint) 下如下的代码的代码屏蔽,那么即使有 USB 设备插入集线器,USB 主机控制器有不会有任何反应:

                       usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq,hub, endpoint->bInterval)

当子集线器 hub端口上有一个设备插入或者拔除时,子集线器会向主机控制器发送中断传输消息,主机控制器会产生中断,例如EHCI 的 interrupt 在 HCD 中被分为了 6 种类型,如下宏定义:

  1.                   // these STS_* flags are also intr_enable bits (USBINTR)
  2.                   #define STS_IAA (1<<5) /* Interrupted on async advance 当要从asynchronous schedule传输队列中移除一个QH时*/
  3.                   #define STS_FATAL (1<<4) /* such as some PCI access errors */
  4.                   #define STS_FLR (1<<3) /* frame list rolled over */
  5.                   #define STS_PCD (1<<2) /* port change detect:root hub上某个端口上有设备插入或拔出所产生的中断,
  6. 需要进一步的读取root hub上各port对应的register判断是插入还是拔出。 */
  7.                   #define STS_ERR (1<<1) /* "error" completion (overflow, ...) */
  8.             #define STS_INT (1<<0) /* "normal" completion (short, ...) 正确完成一次数据传输后所发出的中断*/      

   对于 USB2.0主机控制器 ehci,其中断处理函数在usb_add_hcd()中设置为 usb_hcd_irq,在函数usb_hcd_irq() 中再调用不同主机控制器驱动的中断函数,例如 struct hc_driver ehci_hc_driver.irq = ehci_irq(hdc):

  1. int usb_add_hcd(struct usb_hcd *hcd, unsigned int irqnum, unsigned long irqflags)->
  2. usb_hcd_request_irqs(hcd, irqnum, irqflags)->
  3. request_irq(irqnum, &usb_hcd_irq, irqflags, hcd->irq_descr, hcd);
  4. irqreturn_t usb_hcd_irq (int irq, void *__hcd)->
  5. hcd->driver->irq(hcd) = struct hc_driver ehci_hc_driver.irq = ehci_irq(hdc);
  6. /*
  7. EHCI 的 interrupt 在 HCD 中被分为了 6 种类型,如下宏定义:
  8. // these STS_* flags are also intr_enable bits (USBINTR)
  9. #define STS_IAA (1<<5) /* Interrupted on async advance 当要从asynchronous schedule传输队列中移除一个QH时*/
  10. #define STS_FATAL (1<<4) /* such as some PCI access errors */
  11. #define STS_FLR (1<<3) /* frame list rolled over */
  12. #define STS_PCD (1<<2) /* port change detect:root hub上某个端口上有设备插入或拔出所产生的中断,
  13. 需要进一步的读取root hub上各port对应的register判断是插入还是拔出。 */
  14. #define STS_ERR (1<<1) /* "error" completion (overflow, ...) */
  15. #define STS_INT (1<<0) /* "normal" completion (short, ...) 正确完成一次数据传输后所发出的中断*/
  16. */
  17. status = ehci_readl(ehci, &ehci->regs->status); //读取主机控制器的寄存器
  18. masked_status = status & (INTR_MASK | STS_FLR); //#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
  19. ehci_writel(ehci, masked_status, &ehci->regs->status);/* clear (just) interrupts:清除中断标志位。 */
  20. /* remote wakeup [4.3.1] */
  21. if (status & STS_PCD) // port change detect
  22. {
  23. unsigned i = HCS_N_PORTS (ehci->hcs_params);
  24. u32 ppcd = ~0;
  25. /* kick root hub later */
  26. pcd_status = status;
  27. /* resume root hub? */
  28. if (ehci->rh_state == EHCI_RH_SUSPENDED)
  29. usb_hcd_resume_root_hub(hcd);
  30. /* get per-port change detect bits */
  31. if (ehci->has_ppcd)
  32. ppcd = status >> 16;
  33. while (i--)
  34. {
  35. int pstatus;
  36. ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
  37. usb_hcd_start_port_resume(&hcd->self, i);
  38. mod_timer(&hcd->rh_timer, ehci->reset_done[i])->
  39. expires = apply_slack(timer, expires);
  40. return __mod_timer(timer, expires, false, TIMER_NOT_PINNED);
  41. }
  42. }
  43. ehci_work (ehci)->
  44. ehci->scanning = true;
  45. if (ehci->intr_count > 0)
  46. {
  47. scan_intr(ehci)->
  48. qh_completions(ehci, qh)->
  49. list_entry (entry, struct ehci_qtd, qtd_list);
  50. ehci_urb_done(ehci, last->urb, last_status)->
  51. //ehci-platform 101c0000.usb: ehci_urb_done 1 urb ee71e780 ep1in status 0 len 1/1
  52. ehci_dbg (ehci,
  53. "%s %s urb %p ep%d%s status %d len %d/%d\n",
  54. __func__, urb->dev->devpath, urb,
  55. usb_pipeendpoint (urb->pipe),
  56. usb_pipein (urb->pipe) ? "in" : "out",
  57. status,
  58. urb->actual_length, urb->transfer_buffer_length);
  59. usb_hcd_giveback_urb(ehci_to_hcd(ehci), urb, status)->//主机控制器hcd返还giveback urb
  60. //usb_pipeint用于判断是否属于中断传输
  61. //USB子设备插入集线器时会通过中断传输向主机控制器报告
  62. if (usb_pipeisoc(urb->pipe) || usb_pipeint(urb->pipe))
  63. {
  64. bh = &hcd->high_prio_bh;
  65. high_prio_bh = true;
  66. }
  67. if (high_prio_bh)
  68. {
  69. tasklet_hi_schedule(&bh->bh)->__tasklet_hi_schedule(t)->
  70. raise_softirq_irqoff(HI_SOFTIRQ); //触发软中断
  71. //在函数usb_add_hcd()->init_giveback_urb_bh(&hcd->high_prio_bh)中设置
  72. // tasklet_init(&bh->bh, usb_giveback_urb_bh, (unsigned long)bh);
  73. static void usb_giveback_urb_bh(unsigned long param)->
  74. urb = list_entry(local_list.next, struct urb, urb_list);
  75. list_del_init(&urb->urb_list);
  76. bh->completing_ep = urb->ep;
  77. __usb_hcd_giveback_urb(urb)->
  78. urb->complete(urb);//urb->complete =hub_irq
  79. }
  80. }

 USB硬件上的热拔插

USB设备热拔插hot_plug 主要由集线器完成,集线器最多可以有31端口,集线器会监测每个端口的信号线(D+和D-)的电压,集线器的端口上每条线上都有15k欧姆的下拉电阻,而USB设备有900~1575欧姆的上拉电阻。假如有USB设备连接到集线器的端口,集线器就可以探测到电压,然后通过探测哪端拥有上拉电阻来决定USB设备的通信速度。

集线器的硬件有专门的寄存器存放集线器及其端口的当前状态信息,其中寄存器wHubStatus 存放集线器的状态,参见USB2.0协议的Tabel 11-19

集线器的寄存器wHubChange 存放集线器的状态变化信息,,参见USB2.0协议的Tabel 11-20:

集线器的寄存器wPortStatus存放集线器上端口的当前状态信息,参见USB2.0协议的Tabel 11-21:

集线器的寄存器wPortChange存放集线器上端口的状态变化信息,,参见USB2.0协议的Tabel 11-22:

集线器集线器的请求块struct usb_hub *hub 有一专属的请求块hub->urb用于查询连接在集线器的端口的状态变化信息,集线器的请求块hub->urb在函数hub_configure()中创建:

  1. hub->urb = usb_alloc_urb(0, GFP_KERNEL);
  2. usb_fill_int_urb(hub->urb,hdev,pipe,*hub->buffer,maxp,hub_irq,hub, endpoint->bInterval)->
  3. hub->urb->complete = hub_irq;
  4. hub->urb->transfer_buffer = *hub->buffer;
  5. hub_activate(hub)->
  6. status = usb_submit_urb(hub->urb, GFP_NOIO)->
  7. ep = usb_pipe_endpoint(dev, urb->pipe);
  8. return usb_hcd_submit_urb(urb, mem_flags)->
  9. if (is_root_hub(urb->dev)) //判断 是否为根集线器
  10. {
  11. status = rh_urb_enqueue(hcd, urb);
  12. }
  13. else
  14. {
  15. status = map_urb_for_dma(hcd, urb, mem_flags);
  16. status = hcd->driver->urb_enqueue(hcd, urb, mem_flags) = ehci_urb_enqueue
  17. }

 

USB子设备插入集线器的处理过程

每当 hub端口上有一个设备插入或者拔除时的处理过程如下:

USB设备分为USB子设备 struct usb_device 和USB接口设备struct usb_interface ,USB子设备 struct usb_device 和USB接口设备struct usb_interface对应的驱动结构体都是 struct usb_driver,使用 usb_register() 或者 module_usb_driver()注册,并赋值 for_devices=0,所有的USB子设备 struct usb_device对应的都是通用USB子设备驱动 struct usb_device_driver usb_generic_driver ,其使用usb_register_device_driver(&usb_generic_driver, THIS_MODULE) 注册,因为整个内核源码在函数usb_device_match() 中只有 struct usb_device_driver usb_generic_driver  的 is_usb_device_driver()->return container_of(drv, struct usbdrv_wrap, driver)->for_devices =1 ,

需要驱动开发者开发的只有USB接口设备struct usb_interface  的驱动程序,例如 struct usb_driver hub_driver、struct usb_driver skel_driver、struct usb_driver usb_serial_driver 以及 USB wifi 驱动struct rtw_usb_drv usb_drv ,参见下图:

 

 

每当 hub端口上有一个设备插入或者拔除时,通过各级中断处理函数最终会调用到函数 huq_irq()。

如果将函数hub_configure(hub, endpoint) 下如下的代码的代码屏蔽,那么即使有 USB 设备插入集线器,USB 主机控制器有不会有任何反应:

                       usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq,hub, endpoint->bInterval)

每当有设备连接到USB接口时,USB总线在查询hub状态信息的时候会触发hub的中断服务程序hub_irq ,并最终调用 hub_event:

  1. /* completion function, fires on port status changes and various faults */
  2. static void hub_irq(struct urb *urb)->
  3. struct usb_hub *hub = urb->context;
  4. int status = urb->status;
  5. switch (status)
  6. {
  7. case -ENOENT: /* synchronous unlink */
  8. case -ECONNRESET: /* async unlink */
  9. case -ESHUTDOWN: /* hardware going away */
  10. return;
  11. default: /* presumably an error */
  12. /* Cause a hub reset after 10 consecutive errors */
  13. dev_dbg(hub->intfdev, "transfer --> %d\n", status);
  14. if ((++hub->nerrors < 10) || hub->error)
  15. goto resubmit;
  16. hub->error = status;
  17. /* FALL THROUGH */
  18. /* let hub_wq handle things */
  19. case 0: /* we got data: port status changed */
  20. bits = 0;
  21. for (i = 0; i < urb->actual_length; ++i)
  22. bits |= ((unsigned long) ((*hub->buffer)[i]))<< (i*8);
  23. hub->event_bits[0] = bits;
  24. break;
  25. }
  26. hub->nerrors = 0;
  27. /* Something happened, let hub_wq figure it out */
  28. kick_hub_wq(hub)->
  29. queue_work(hub_wq, &hub->events)->//INIT_WORK(&hub->events, hub_event);
  30. static void hub_event(struct work_struct *work)
  31. usb_submit_urb(hub->urb, GFP_ATOMIC); //重新向主机控制器提交中断传输请求 hub->urb

集线器的热插拔处理与集线器驱动hub_driver

每当有设备连接到USB接口时,USB总线在查询hub状态信息的时候会触发hub的中断服务程序hub_irq ,并最终调用 hub_event:

  1. static void hub_event(struct work_struct *work)
  2. struct usb_hub *hub = container_of(work, struct usb_hub, events);
  3. struct usb_device *hdev = hub->hdev;
  4. struct device *hub_dev = hub->intfdev;
  5. struct usb_interface *intf = to_usb_interface(hub_dev);
  6. //对于USB2.0 的 root hub 实际打印:hub 2-0:1.0: state 7 ports 1 chg 0002 evt 0000
  7. //对于 GL852G 集线器有4个端口,实际打印:hub 2-1:1.0: state 7 ports 4 chg 0000 evt 0002
  8. dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
  9. hdev->state, hdev->maxchild,
  10. /* NOTE: expects max 15 ports... */
  11. (u16) hub->change_bits[0],
  12. (u16) hub->event_bits[0]);
  13. for (i = 1; i <= hdev->maxchild; i++) //遍历集线器的每个端口
  14. {
  15. struct usb_port *port_dev = hub->ports[i - 1];
  16. if (test_bit(i, hub->event_bits)
  17. || test_bit(i, hub->change_bits)
  18. || test_bit(i, hub->wakeup_bits)) //如果这几个条件都满足,就port_event
  19. {
  20. port_event(hub, i)->
  21. struct usb_port *port_dev = hub->ports[port1 - 1];
  22. struct usb_device *udev = port_dev->child;
  23. struct usb_device *hdev = hub->hdev;
  24. connect_change = test_bit(port1, hub->change_bits);
  25. clear_bit(port1, hub->event_bits);
  26. clear_bit(port1, hub->wakeup_bits);
  27. hub_port_status(hub, port1, &portstatus, &portchange)->
  28. get_port_status(hub->hdev, port1, &hub->status->port)->
  29. for (i = 0; i < USB_STS_RETRIES && //尝试读取5次: #define USB_STS_RETRIES 5
  30. (status == -ETIMEDOUT || status == -EPIPE); i++) {
  31. status = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
  32. USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port1,
  33. data, sizeof(*data), USB_STS_TIMEOUT);
  34. }
  35. if (portchange & USB_PORT_STAT_C_CONNECTION) {
  36. usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION);
  37. connect_change = 1;
  38. }
  39. if (connect_change) //集线器上的端口状态发生变化
  40. {
  41. hub_port_connect_change(hub, port1, portstatus, portchange)->//处理端口改变的情况
  42. struct usb_port *port_dev = hub->ports[port1 - 1];
  43. struct usb_device *udev = port_dev->child;
  44. //对于USB2.0 的 root hub 实际打印:usb usb2-port1: status 0501, change 0000, 480 Mb/s
  45. dev_dbg(&port_dev->dev, "status %04x, change %04x, %s\n", portstatus,
  46. portchange, portspeed(hub, portstatus));
  47. hub_port_connect(hub, port1, portstatus, portchange)->
  48. struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
  49. struct usb_port *port_dev = hub->ports[port1 - 1];
  50. /* Disconnect any existing devices under this port */
  51. if (udev)
  52. {
  53. //断开该端口设备的连接:如果是root hub,挂接在控制器上的,则断开该端口下的设备。
  54. if (hcd->usb_phy && !hdev->parent)
  55. usb_phy_notify_disconnect(hcd->usb_phy, udev->speed);
  56. usb_disconnect(&port_dev->child);
  57. }
  58. //static bool use_both_schemes = 1;
  59. for (i = 0; i < SET_CONFIG_TRIES; i++) //#define SET_CONFIG_TRIES (2 * (use_both_schemes + 1))
  60. {
  61. /* reallocate for each attempt, since references
  62. * to the previous one can escape in various ways
  63. */
  64. //分配usb设备内存并初始化bus、type、group、设备在系统中的路径(dev->path)、ep0的属性并设置设备状态为attached。
  65. udev = usb_alloc_dev(hdev, hdev->bus, port1)->
  66. struct usb_hcd *usb_hcd = bus_to_hcd(bus);
  67. struct usb_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  68. device_initialize(&dev->dev);
  69. dev->dev.bus = &usb_bus_type;
  70. dev->dev.type = &usb_device_type; //代表USB子设备,而非USB接口interface,is_usb_device(dev)
  71. dev->dev.groups = usb_device_groups;
  72. dev->dev.dma_mask = bus->controller->dma_mask;
  73. set_dev_node(&dev->dev, dev_to_node(bus->controller));
  74. dev->state = USB_STATE_ATTACHED;
  75. dev->lpm_disable_count = 1;
  76. atomic_set(&dev->urbnum, 0);
  77. INIT_LIST_HEAD(&dev->ep0.urb_list);
  78. dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;
  79. dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;
  80. /* ep0 maxpacket comes later, from device descriptor */
  81. usb_enable_endpoint(dev, &dev->ep0, false);
  82. dev->can_submit = 1;
  83. /* Save readable and stable topology id, distinguishing devices
  84. * by location for diagnostics, tools, driver model, etc. The
  85. * string is a path along hub ports, from the root. Each device's
  86. * dev->devpath will be stable until USB is re-cabled, and hubs
  87. * are often labeled with these port numbers. The name isn't
  88. * as stable: bus->busnum changes easily from modprobe order,
  89. * cardbus or pci hotplugging, and so on.
  90. */
  91. if (unlikely(!parent))
  92. {
  93. dev->devpath[0] = '0';
  94. dev->route = 0;
  95. dev->dev.parent = bus->controller;
  96. dev_set_name(&dev->dev, "usb%d", bus->busnum);
  97. root_hub = 1;
  98. }
  99. else
  100. {
  101. /* match any labeling on the hubs; it's one-based */
  102. if (parent->devpath[0] == '0')
  103. {
  104. snprintf(dev->devpath, sizeof dev->devpath,"%d", port1);
  105. /* Root ports are not counted in route string */
  106. dev->route = 0;
  107. }
  108. else
  109. {
  110. snprintf(dev->devpath, sizeof dev->devpath, "%s.%d", parent->devpath, port1);
  111. /* Route string assumes hubs have less than 16 ports */
  112. if (port1 < 15)
  113. dev->route = parent->route +(port1 << ((parent->level - 1)*4));
  114. else
  115. dev->route = parent->route +(15 << ((parent->level - 1)*4));
  116. }
  117. dev->dev.parent = &parent->dev;
  118. dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath);
  119. /* hub driver sets up TT records */
  120. }
  121. dev->portnum = port1;
  122. dev->bus = bus;
  123. dev->parent = parent;
  124. INIT_LIST_HEAD(&dev->filelist);
  125. if (root_hub) /* Root hub always ok [and always wired] */
  126. dev->authorized = 1;
  127. else
  128. {
  129. dev->authorized = !!HCD_DEV_AUTHORIZED(usb_hcd);
  130. dev->wusb = usb_bus_is_wusb(bus) ? 1 : 0;
  131. }
  132. usb_set_device_state(udev, USB_STATE_POWERED);
  133. udev->bus_mA = hub->mA_per_port;
  134. udev->level = hdev->level + 1;
  135. udev->wusb = hub_is_wusb(hub);
  136. /* Devices connected to SuperSpeed hubs are USB 3.0 or later */
  137. if (hub_is_superspeed(hub->hdev))//判断速度是否为高速
  138. udev->speed = USB_SPEED_SUPER;
  139. else
  140. udev->speed = USB_SPEED_UNKNOWN;
  141. choose_devnum(udev)->//获取设备号,在usbfs中,设备号被用作文件名.
  142. devnum = find_next_zero_bit(bus->devmap.devicemap, 128, bus->devnum_next);
  143. /* reset (non-USB 3.0 devices) and get descriptor */
  144. status = hub_port_init(hub, udev, port1, i)->//初始化设备,设置地址,读取设备描述符
  145. struct usb_device *hdev = hub->hdev;
  146. struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
  147. const char *speed = usb_speed_string(udev->speed);
  148. /*
  149. static const char *const speed_names[] = {
  150. [USB_SPEED_UNKNOWN] = "UNKNOWN",
  151. [USB_SPEED_LOW] = "low-speed",
  152. [USB_SPEED_FULL] = "full-speed",
  153. [USB_SPEED_HIGH] = "high-speed",
  154. [USB_SPEED_WIRELESS] = "wireless",
  155. [USB_SPEED_SUPER] = "super-speed",
  156. [USB_SPEED_SUPER_PLUS] = "super-speed-plus",
  157. };
  158. */
  159. if (speed < 0 || speed >= ARRAY_SIZE(speed_names))
  160. {
  161. speed = USB_SPEED_UNKNOWN;
  162. }
  163. return speed_names[speed];
  164. //对于连接在 USB2.0 的 root hub 上的 GL852G hub 芯片,
  165. //实际打印:usb 2-1: new high-speed USB device number 2 using ehci-platform
  166. dev_info(&udev->dev,
  167. "%s %s USB device number %d using %s\n",
  168. (udev->config) ? "reset" : "new", speed,
  169. devnum, udev->bus->controller->driver->name);
  170. for (retries = 0; retries < GET_DESCRIPTOR_TRIES; (++retries, msleep(100)))
  171. {
  172. /*
  173. scheme,方案,计划的意思。那么 old scheme, both scheme 这两个词组
  174. 似乎已经反映出来说有两个方案,一个旧的,一个新的。这是怎么回事?
  175. 什么方面的方案?一个是来自Linux 的方案,一个是来自 Windows 的方案,
  176. 目的是为了获得设备的描述符。
  177. */
  178. if (use_new_scheme(udev, retry_counter))->return USE_NEW_SCHEME(retry);
  179. {
  180. struct usb_device_descriptor *buf;
  181. int r = 0;
  182. did_new_scheme = true;
  183. retval = hub_enable_device(udev);
  184. #define GET_DESCRIPTOR_BUFSIZE 64
  185. buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO);
  186. for (operations = 0; operations < 3; ++operations)
  187. {
  188. buf->bMaxPacketSize0 = 0;
  189. r = usb_control_msg(udev, usb_rcvaddr0pipe(),
  190. USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
  191. USB_DT_DEVICE << 8, 0,
  192. buf, GET_DESCRIPTOR_BUFSIZE,
  193. initial_descriptor_timeout);
  194. switch (buf->bMaxPacketSize0) {
  195. case 8: case 16: case 32: case 64: case 255:
  196. if (buf->bDescriptorType ==
  197. USB_DT_DEVICE) {
  198. r = 0;
  199. break;
  200. }
  201. }
  202. }
  203. udev->descriptor.bMaxPacketSize0 = buf->bMaxPacketSize0;
  204. #undef GET_DESCRIPTOR_BUFSIZE
  205. }
  206. }
  207. //获取USB子设备描述符struct usb_device_descriptor
  208. usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE)->
  209. struct usb_device_descriptor *desc = kmalloc(sizeof(*desc), GFP_NOIO);
  210. usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size)->
  211. usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
  212. USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
  213. (type << 8) + index, 0, buf, size,
  214. USB_CTRL_GET_TIMEOUT);
  215. memcpy(&dev->descriptor, desc, size);
  216. usb_detect_quirks(udev)->//找出怪胎
  217. udev->quirks = __usb_detect_quirks(udev, usb_quirk_list);
  218. /* Run it through the hoops (find a driver, etc) */
  219. status = usb_new_device(udev)->
  220. usb_enumerate_device(udev)-> /* Read descriptors */
  221. struct usb_hcd *hcd = bus_to_hcd(udev->bus);
  222. usb_get_configuration(udev);
  223. /* read the standard strings and cache them if present */
  224. udev->product = usb_cache_string(udev, udev->descriptor.iProduct);
  225. udev->manufacturer = usb_cache_string(udev, udev->descriptor.iManufacturer);
  226. udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);
  227. err = usb_enumerate_device_otg(udev);
  228. usb_detect_interface_quirks(udev);
  229. //对于 USB2.0 root hub 下接的 GL852G hub 芯片,实际打印:usb 2-1: udev 2, busnum 2, minor = 129
  230. dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n",
  231. udev->devnum, udev->bus->busnum,
  232. (((udev->bus->busnum-1) * 128) + (udev->devnum-1)));
  233. /* export the usbdev device-node for libusb */
  234. //#define USB_DEVICE_MAJOR 189
  235. udev->dev.devt=MKDEV(USB_DEVICE_MAJOR, (((udev->bus->busnum-1) * 128) + (udev->devnum-1)));
  236. announce_device(udev)-> /* Tell the world! 告诉全世界我诞生了 */
  237. /*
  238. 对于 USB2.0 的 root hub 实际打印:
  239. usb 2-1: New USB device found, idVendor=05e3, idProduct=0610
  240. usb 2-1: New USB device strings: Mfr=0, Product=1, SerialNumber=0
  241. usb 2-1: Product: USB2.0 Hub
  242. */
  243. dev_info(&udev->dev, "New USB device found, idVendor=%04x, idProduct=%04x\n",
  244. le16_to_cpu(udev->descriptor.idVendor),
  245. le16_to_cpu(udev->descriptor.idProduct));
  246. dev_info(&udev->dev,
  247. "New USB device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",
  248. udev->descriptor.iManufacturer,
  249. udev->descriptor.iProduct,
  250. udev->descriptor.iSerialNumber);
  251. show_string(udev, "Product", udev->product);
  252. show_string(udev, "Manufacturer", udev->manufacturer);
  253. show_string(udev, "SerialNumber", udev->serial);
  254. device_enable_async_suspend(&udev->dev);
  255. device_add(&udev->dev);
  256. if (hcd->usb_phy && !hdev->parent)
  257. {
  258. usb_phy_notify_connect(hcd->usb_phy,udev->speed);
  259. }
  260. status = hub_power_remaining(hub);
  261. }

当USB子设备连接到集线器hub 的某个端口时,会读取USB子设备的描述符,以便确定USB子设备的类型,然后调用usb_alloc_dev()和usb_new_device() 创建struct usb_device *dev :

  1. udev = usb_alloc_dev(hdev, hdev->bus, port1)->
  2. struct usb_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  3. dev->dev.bus = &usb_bus_type; //代表USB子设备,而非USB接口interface,is_usb_device(dev)
  4. dev->dev.type = &usb_device_type;
  5. status = usb_new_device(udev)->
  6. usb_enumerate_device(udev)-> /* Read descriptors */
  7. struct usb_hcd *hcd = bus_to_hcd(udev->bus);
  8. usb_get_configuration(udev);
  9. /* read the standard strings and cache them if present */
  10. udev->product = usb_cache_string(udev, udev->descriptor.iProduct);
  11. udev->manufacturer = usb_cache_string(udev, udev->descriptor.iManufacturer);
  12. udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);
  13. err = usb_enumerate_device_otg(udev);
  14. usb_detect_interface_quirks(udev);
  15. //对于 USB2.0 root hub 下接的 GL852G hub 芯片,实际打印:usb 2-1: udev 2, busnum 2, minor = 129
  16. dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n",
  17. udev->devnum, udev->bus->busnum,
  18. (((udev->bus->busnum-1) * 128) + (udev->devnum-1)));
  19. /* export the usbdev device-node for libusb */
  20. //#define USB_DEVICE_MAJOR 189
  21. udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, (((udev->bus->busnum-1) * 128) + (udev->devnum-1)));
  22. announce_device(udev); /* Tell the world! 告诉全世界我诞生了 */
  23. device_enable_async_suspend(&udev->dev);
  24. device_add(&udev->dev);

函数usb_new_device() 最终调用device_add() 在 USB 总线 struct bus_type usb_bus_type 上注册的驱动程序,在USB 总线 struct bus_type usb_bus_type 存在一个特殊的USB通用驱动struct usb_device_driver usb_generic_driver,所有的USB子设备 struct usb_device对应的都是通用USB子设备驱动 struct usb_device_driver usb_generic_driver注意其中的 new_udriver->drvwrap.for_devices = 1 ,在函数is_usb_device_driver() 中会判断 for_devices 的值 ,使用 usb_register() 或者 module_usb_driver()注册的USB接口设备struct usb_interface  的驱动程序会赋值new_udriver->drvwrap.for_devices = 0,例如 struct usb_driver hub_driver、struct usb_driver skel_driver、struct usb_driver usb_serial_driver 以及 USB wifi 驱动struct rtw_usb_drv usb_drv

  1. int usb_register_device_driver(struct usb_device_driver *new_udriver, struct module *owner)
  2. {
  3. new_udriver->drvwrap.for_devices = 1; //在函数is_usb_device_driver() 中会判断 for_devices 的值
  4. new_udriver->drvwrap.driver.name = new_udriver->name;
  5. new_udriver->drvwrap.driver.bus = &usb_bus_type;
  6. new_udriver->drvwrap.driver.probe = usb_probe_device;
  7. new_udriver->drvwrap.driver.remove = usb_unbind_device;
  8. new_udriver->drvwrap.driver.owner = owner;
  9. }

创建USB子设备 struct usb_device 匹配的就是驱动程序 struct usb_device_driver usb_generic_driver,当执行 device_add() 是调用的是其探测函数为 generic_probe

                  struct usb_device_driver usb_generic_driver = {

                                   .name = "usb",

                                   .probe = generic_probe,

                                   .disconnect = generic_disconnect,

                                   .suspend = generic_suspend,

                                   .resume = generic_resume,

                                   .supports_autosuspend = 1,

                  };

USB子设备 struct usb_device 执行 device_add()的过程中匹配的驱动程序是struct usb_device_driver usb_generic_driver 如下:

  1. struct usb_device_driver usb_generic_driver = {
  2. .name = "usb",
  3. .probe = generic_probe,
  4. .disconnect = generic_disconnect,
  5. .suspend = generic_suspend,
  6. .resume = generic_resume,
  7. .supports_autosuspend = 1,
  8. };
  9. USB子设备 struct usb_device 执行 device_add()的过程中匹配的驱动程序是struct usb_device_driver usb_generic_driver, 如下:
  10. udev = usb_alloc_dev(hdev, hdev->bus, port1)->
  11. struct usb_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  12. dev->dev.bus = &usb_bus_type; //代表USB子设备,而非USB接口interface,is_usb_device(dev)
  13. dev->dev.type = &usb_device_type;
  14. status = usb_new_device(udev)->
  15. usb_enumerate_device(udev)-> /* Read descriptors */
  16. announce_device(udev); /* Tell the world! 告诉全世界我诞生了 */
  17. device_enable_async_suspend(&udev->dev);
  18. device_add(&udev->dev)->
  19. dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id);
  20. // 对于 USB2.0 的 root hub 实际打印:device: 'usb2': device_add
  21. pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
  22. error = bus_add_device(dev)->
  23. struct bus_type *bus = bus_get(dev->bus);
  24. //对于 USB2.0 的 root hub 实际打印: bus: 'usb': add device usb2
  25. pr_debug("bus: '%s': add device %s\n", bus->name, dev_name(dev));
  26. error = sysfs_create_link(&dev->kobj, &dev->bus->p->subsys.kobj, "subsystem");
  27. klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);
  28. blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_ADD_DEVICE, dev);
  29. kobject_uevent(&dev->kobj, KOBJ_ADD);
  30. bus_probe_device(dev)->device_initial_probe(dev)->__device_attach(dev, true)->
  31. bus_for_each_drv(dev->bus, NULL, &data, _device_attach_driver)-> //在 USB 总线 struct bus_type usb_bus_type 上注册的驱动程序
  32. while ((drv = next_driver(&i)) && !error) //在 USB 总线 struct bus_type usb_bus_type 上注册的驱动程序
  33. {
  34. error = fn(drv, data)=_device_attach_driver;
  35. static int __device_attach_driver(struct device_driver *drv, void *_data)->
  36. if (!driver_match_device(drv, dev))-> //在 USB 总线 struct bus_type usb_bus_type 上匹配到驱动时返回值 为 1
  37. return drv->bus->match ? drv->bus->match(dev, drv) : 1;
  38. struct bus_type usb_bus_type.match = usb_device_match,
  39. // usb_device_match 有匹配的驱动时返回值为 1
  40. //在函数usb_alloc_dev() 中设置 dev->dev.type = &usb_device_type;
  41. static int usb_device_match(struct device *dev, struct device_driver *drv)
  42. {
  43. /* devices and interfaces are handled separately */
  44. //对于 usb子设备 ,is_usb_device(dev) 的返回值为 true
  45. //在函数usb_alloc_dev() 中设置 dev->dev.type = &usb_device_type;
  46. if (is_usb_device(dev)) //return dev->type == &usb_device_type;
  47. {
  48. /* interface drivers never match devices */
  49. //对于 USB通用驱动struct usb_device_driver usb_generic_driver, is_usb_device_driver() 返回值为1
  50. if (!is_usb_device_driver(drv))->
  51. return container_of(drv, struct usbdrv_wrap, driver)->for_devices;
  52. {
  53. return 0;
  54. }
  55. /* TODO: Add real matching code */
  56. return 1;
  57. }
  58. //在函数usb_set_configuration()中设置:intf->dev.type = &usb_if_device_type;
  59. else if (is_usb_interface(dev)) -> return dev->type == &usb_if_device_type; // 匹配USB接口设备的驱动
  60. {
  61. struct usb_interface *intf;
  62. struct usb_driver *usb_drv;
  63. const struct usb_device_id *id;
  64. /* device drivers never match interfaces */
  65. if (is_usb_device_driver(drv))
  66. return 0;
  67. intf = to_usb_interface(dev);
  68. usb_drv = to_usb_driver(drv);
  69. id = usb_match_id(intf, usb_drv->id_table);
  70. if (id)
  71. return 1;
  72. id = usb_match_dynamic_id(intf, usb_drv);
  73. if (id)
  74. return 1;
  75. }
  76. return 0;
  77. }
  78. {
  79. return 0;
  80. }
  81. return driver_probe_device(drv, dev)-> //在 USB 总线 struct bus_type usb_bus_type 上匹配到驱动时执行到这里
  82. //对于 USB2.0 的 root hub 实际打印: bus: 'usb': driver_probe_device: matched device usb2 with driver usb
  83. pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
  84. drv->bus->name, __func__, dev_name(dev), drv->name);
  85. really_probe(dev, drv)->
  86. //对于 USB2.0 的 root hub 实际打印: bus: 'usb': driver_probe_device: matched device usb2 with driver usb
  87. pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
  88. drv->bus->name, __func__, drv->name, dev_name(dev));
  89. dev->driver = drv;
  90. // 所有USB子设备struct usb_device和USB接口设备struct usb_interface 都挂在USB总线上struct struct bus_type usb_bus_type
  91. if (dev->bus->probe) //struct struct bus_type usb_bus_type.probe = NULL
  92. {
  93. /*
  94. struct bus_type usb_bus_type = {
  95. .name = "usb",
  96. .match = usb_device_match,
  97. .uevent = usb_uevent,
  98. .need_parent_lock = true,
  99. };
  100. */
  101. ret = dev->bus->probe(dev);
  102. }
  103. else if (drv->probe) //USB子设备 struct usb_device 驱动的情况
  104. {
  105. /*
  106. struct bus_type usb_bus_type = {
  107. .name = "usb",
  108. .match = usb_device_match,
  109. .uevent = usb_uevent,
  110. .need_parent_lock = true,
  111. };
  112. */
  113. ret = drv->probe(dev); //匹配到USB通用驱动struct usb_device_driver usb_generic_driver
  114. static int generic_probe(struct usb_device *udev)->
  115. usb_choose_configuration(udev)->
  116. num_configs = udev->descriptor.bNumConfigurations;
  117. usb_get_max_power(udev, c);
  118. i = best->desc.bConfigurationValue;
  119. //对于 USB2.0 的 root hub 连接的 GL852G hub 芯片打印:usb 2-1: configuration #1 chosen from 1 choice
  120. dev_dbg(&udev->dev, "configuration #%d chosen from %d choice%s\n",
  121. i, num_configs, plural(num_configs));
  122. usb_set_configuration(udev, c)->
  123. int nintf = cp->desc.bNumInterfaces;
  124. struct usb_interface **new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),
  125. i = dev->bus_mA - usb_get_max_power(dev, cp);
  126. usb_autoresume_device(dev);
  127. usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
  128. struct usb_host_interface *alt = usb_altnum_to_altsetting(intf, 0);
  129. struct usb_interface *intf->cur_altsetting = alt;
  130. usb_enable_interface(dev, intf, true);
  131. intf->dev.parent = &dev->dev;
  132. intf->dev.driver = NULL;
  133. intf->dev.bus = &usb_bus_type;
  134. intf->dev.type = &usb_if_device_type; //USB 子设备
  135. intf->dev.groups = usb_interface_groups;
  136. intf->dev.dma_mask = dev->dev.dma_mask;
  137. INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);
  138. /*
  139. static void __usb_queue_reset_device(struct work_struct *ws)->
  140. usb_reset_device(udev)-> usb_reset_and_verify_device(udev)->
  141. usb_ep0_reinit(udev);
  142. descriptors_changed(udev, &descriptor, bos)->
  143. usb_string(udev, udev->descriptor.iSerialNumber,buf, serial_len)->
  144. usb_get_langid(dev, tbuf)->
  145. //对于 GL852G hub 芯片实际打印:usb 2-1: default language 0x0409
  146. usb_string_sub(dev, dev->string_langid, index, tbuf);
  147. usb_string_sub(dev, dev->string_langid, index, tbuf);
  148. */
  149. intf->minor = -1;
  150. device_initialize(&intf->dev);
  151. pm_runtime_no_callbacks(&intf->dev);
  152. dev_set_name(&intf->dev, "%d-%s:%d.%d",
  153. dev->bus->busnum, dev->devpath,
  154. configuration, alt->desc.bInterfaceNumber);
  155. usb_get_dev(dev);
  156. usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
  157. USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
  158. NULL, 0, USB_CTRL_SET_TIMEOUT);
  159. usb_set_device_state(dev, USB_STATE_CONFIGURED);
  160. for (i = 0; i < nintf; ++i)
  161. {
  162. struct usb_interface *intf = cp->interface[i];
  163. /*
  164. 对于 USB2.0 的 root hub 连接的 GL852G hub 芯片实际打印:
  165. usb 2-1: adding 2-1:1.0 (config #1, interface 0)
  166. root@mxlos:/sys/bus/usb/drivers/usb/usb2/2-1/2-1:1.0# ls
  167. 2-1-port1 2-1-port3 authorized
  168. bInterfaceClass bInterfaceProtocol bNumEndpoints
  169. ep_81 power supports_autosuspend
  170. 2-1-port2 2-1-port4 bAlternateSetting
  171. bInterfaceNumber bInterfaceSubClass driver
  172. modalias subsystem uevent
  173. root@mxlos:/sys/bus/usb/drivers/usb/usb2/2-1/2-1:1.0# cat modalias
  174. usb:v05E3p0610d6160dc09dsc00dp02ic09isc00ip02in00
  175. root@mxlos:/sys/bus/usb/drivers/usb/usb2/2-1/2-1:1.0# cat bInterfaceClass
  176. 09
  177. root@mxlos:/sys/bus/usb/drivers/usb/usb2/2-1/2-1:1.0# cat uevent
  178. DEVTYPE=usb_interface
  179. DRIVER=hub
  180. PRODUCT=5e3/610/6160
  181. TYPE=9/0/2
  182. INTERFACE=9/0/2
  183. MODALIAS=usb:v05E3p0610d6160dc09dsc00dp02ic09isc00ip02in00
  184. root@mxlos:/sys/bus/usb/drivers/usb/usb2/2-1/2-1:1.0#
  185. */
  186. dev_dbg(&dev->dev,
  187. "adding %s (config #%d, interface %d)\n",
  188. dev_name(&intf->dev), configuration,
  189. intf->cur_altsetting->desc.bInterfaceNumber);
  190. device_enable_async_suspend(&intf->dev);
  191. ret = device_add(&intf->dev)->
  192. dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id);
  193. //对于USB2.0 的 root hub 的 interface 0 实际打印: device: '2-0:1.0': device_add
  194. pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
  195. kobject_uevent(&dev->kobj, KOBJ_ADD);
  196. bus_probe_device(dev);
  197. create_intf_ep_devs(intf);
  198. }
  199. usb_notify_add_device(udev)->
  200. blocking_notifier_call_chain(&usb_notifier_list, USB_DEVICE_ADD, udev);
  201. }
  202. }
  203. else if (drv->probe) //USB接口子设备 struct usb_interface 驱动的情况
  204. {
  205. //对于 usb hub 驱动 struct usb_driver hub_driver hub.drvwrap.driver.probe = usb_probe_interface
  206. ret = drv->probe(dev)=usb_probe_interface;
  207. static int usb_probe_interface(struct device *dev)->
  208. struct usb_device_id *id = usb_match_dynamic_id(intf, driver);
  209. if (!id)
  210. {
  211. id = usb_match_id(intf, driver->id_table)->
  212. for (; id->idVendor || id->idProduct || id->bDeviceClass ||
  213. id->bInterfaceClass || id->driver_info; id++) {
  214. if (usb_match_one_id(interface, id))->
  215. intf = interface->cur_altsetting;
  216. dev = interface_to_usbdev(interface);
  217. if (!usb_match_device(dev, id))
  218. return 0;
  219. return usb_match_one_id_intf(dev, intf, id);
  220. {
  221. return id;
  222. }
  223. }
  224. }
  225. dev_dbg(dev, "%s - got id\n", __func__);
  226. driver->probe(intf, id);//对于 usb hub 驱动 struct usb_driver hub_driver.probe = hub_probe
  227. static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)->
  228. dev_info(&intf->dev, "USB hub found\n");/* We found a hub */
  229. struct usb_hub *hub = kzalloc(sizeof(*hub), GFP_KERNEL);
  230. hub->intfdev = &intf->dev;
  231. hub->hdev = hdev;
  232. INIT_DELAYED_WORK(&hub->leds, led_work);
  233. INIT_DELAYED_WORK(&hub->init_work, NULL);
  234. INIT_WORK(&hub->events, hub_event);
  235. usb_get_intf(intf);
  236. usb_get_dev(hdev);
  237. usb_set_intfdata(intf, hub);
  238. intf->needs_remote_wakeup = 1;
  239. hub_configure(hub, endpoint)->
  240. struct usb_hub *hub->buffer = kmalloc(sizeof(*hub->buffer), GFP_KERNEL);
  241. hub->status = kmalloc(sizeof(*hub->status), GFP_KERNEL);
  242. hub->descriptor = kzalloc(sizeof(*hub->descriptor), GFP_KERNEL);
  243. get_hub_descriptor(hdev, hub->descriptor); //Request the entire hub descriptor.
  244. maxchild = hub->descriptor->bNbrPorts;
  245. //对于 USB2.0 的 root hub 实际打印: hub 2-0:1.0: 1 port detected
  246. dev_info(hub_dev, "%d port%s detected\n", maxchild, (maxchild == 1) ? "" : "s");
  247. hub->ports = kzalloc(maxchild * sizeof(struct usb_port *), GFP_KERNEL);
  248. wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics);
  249. //对于 USB2.0 的 root hub 实际打印:hub 2-0:1.0: standalone hub
  250. dev_dbg(hub_dev, "standalone hub\n");
  251. switch (wHubCharacteristics & HUB_CHAR_LPSM)
  252. {
  253. case HUB_CHAR_COMMON_LPSM:
  254. dev_dbg(hub_dev, "ganged power switching\n");
  255. break;
  256. case HUB_CHAR_INDV_PORT_LPSM:
  257. //对USB2.0 的 root hub 实际打印:hub 2-0:1.0: individual port power switching
  258. dev_dbg(hub_dev, "individual port power switching\n");
  259. break;
  260. case HUB_CHAR_NO_LPSM:
  261. case HUB_CHAR_LPSM:
  262. dev_dbg(hub_dev, "no power switching (usb 1.0)\n");
  263. break;
  264. }
  265. switch (wHubCharacteristics & HUB_CHAR_OCPM) {
  266. case HUB_CHAR_COMMON_OCPM:
  267. dev_dbg(hub_dev, "global over-current protection\n");
  268. break;
  269. case HUB_CHAR_INDV_PORT_OCPM:
  270. //对USB2.0 的 root hub 打印:hub 2-0:1.0: individual port over-current protection
  271. dev_dbg(hub_dev, "individual port over-current protection\n");
  272. break;
  273. case HUB_CHAR_NO_OCPM:
  274. case HUB_CHAR_OCPM:
  275. dev_dbg(hub_dev, "no over-current protection\n");
  276. break;
  277. }
  278. INIT_LIST_HEAD(&hub->tt.clear_list);
  279. INIT_WORK(&hub->tt.clear_work, hub_tt_work);
  280. //对于 USB2.0 的 root hub 实际打印:hub 2-0:1.0: power on to power good time: 20ms
  281. dev_dbg(hub_dev, "power on to power good time: %dms\n",
  282. hub->descriptor->bPwrOn2PwrGood * 2);
  283. usb_get_status(hdev, USB_RECIP_DEVICE, 0, &hubstatus);
  284. hcd = bus_to_hcd(hdev->bus);
  285. hub_hub_status(hub, &hubstatus, &hubchange);
  286. //对于 USB2.0 的 root hub 实际打印:hub 2-0:1.0: local power source is good
  287. dev_dbg(hub_dev, "local power source is %s\n",
  288. (hubstatus & HUB_STATUS_LOCAL_POWER)
  289. ? "lost (inactive)" : "good");
  290. hub->urb = usb_alloc_urb(0, GFP_KERNEL);
  291. usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq, hub, endpoint->bInterval);
  292. for (i = 0; i < maxchild; i++)
  293. {
  294. ret = usb_hub_create_port_device(hub, i + 1)->
  295. struct usb_port *port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL);
  296. port_dev->req = kzalloc(sizeof(*(port_dev->req)), GFP_KERNEL);
  297. hub->ports[port1 - 1] = port_dev;
  298. port_dev->portnum = port1;
  299. set_bit(port1, hub->power_bits);
  300. port_dev->dev.parent = hub->intfdev;
  301. port_dev->dev.groups = port_dev_group;
  302. port_dev->dev.type = &usb_port_device_type;
  303. port_dev->dev.driver = &usb_port_driver;
  304. //对于 USB2.0 的 root hub 上的第一个USB子设备名为 : usb2-port1
  305. dev_set_name(&port_dev->dev, "%s-port%d",
  306. dev_name(&hub->hdev->dev), port1);
  307. device_register(&port_dev->dev)->
  308. device_initialize(dev);
  309. return device_add(dev);
  310. }
  311. hub_activate(hub, HUB_INIT)->
  312. delay = hub_power_on_good_delay(hub);
  313. hub_power_on(hub, false)->
  314. //对于 USB2.0 的 root hub 实际打印:hub 2-0:1.0: enabling power on all ports
  315. dev_dbg(hub->intfdev, "enabling power on all ports\n");
  316. INIT_DELAYED_WORK(&hub->init_work, hub_init_func2);
  317. queue_delayed_work(system_power_efficient_wq,
  318. &hub->init_work,
  319. msecs_to_jiffies(delay));
  320. init3:
  321. usb_submit_urb(hub->urb, GFP_NOIO); //提交urb,等执行完成就会回调hub_irq
  322. /* Scan all ports that need attention */
  323. kick_hub_wq(hub)->
  324. intf = to_usb_interface(hub->intfdev);
  325. //INIT_WORK(&hub->events, hub_event);
  326. queue_work(hub_wq, &hub->events)//把hub_event加入工作队列,开始运行
  327. intf->condition = USB_INTERFACE_BOUND;
  328. }
  329. driver_bound(dev);
  330. //对于 USB2.0 的 root hub 实际打印: bus: 'usb': really_probe: bound device usb2 to driver usb
  331. pr_debug("bus: '%s': %s: bound device %s to driver %s\n",
  332. drv->bus->name, __func__, dev_name(dev), drv->name);
  333. }

普通USB子设备的热插拔处理

设备 (struct usb_device) 、配置 (struct usb_host_config) 、接口 (struct usb_interface)、 设置(struct usb_host_interface)、端点 (struct usb_host_endpoint) 之间的关系如下:

USB子设备struct usb_device 是由一些配置 (struct usb_host_config) 、接口 (struct usb_interface)、 设置(struct usb_host_interface)、端点 (struct usb_host_endpoint)组成,即一个USB设备可以含有一个或多个配置,在每个配置中可含有一个或多个接口,在每个接口中可含有若干个端点。一个USB设备驱动可能包含多个子驱动。一个USB设备子驱动程序对应一个USB接口,而非整个USB设备。

  1. 设备 (struct usb_device) :就是一个实实在在的USB设备,比如集线器Hub、鼠标、键盘、打印机、U盘。
  2. 配置 (struct usb_host_config):一个USB设备可以有一种或者几种配置。没见过具体的USB设备?那么手机见过吧,每个手机都会有多种配置,或者说“设定”。比如,我的这款Nokia 6300手机,手机语言可以设定为English、繁体中文、简体中文,一旦选择了其中一种,那么手机里边所显示的所有的信息都是该种语言/字体。再举一个最简单的例子,操作模式也有好几种,标准、无声、会议等。如果我设为“会议”模式,那么就是只振动不发声,要是设为“无声”模式,那么就啥动静也不会有,只能凭感觉了,以前去公司面试的话通常就是设为“无声”模式,因为觉得振动也不好,让人家面试官听到了还是不合适。那么USB设备的配置也是如此,不同的USB设备当然有不同的配置了,或者说需要配置哪些东西也会不一样。比如4G上网卡就有2种配置:U盘、上网卡。第1次把4G上网卡插入电脑时,它是一个U盘,可以安装里面的程序。装好程序后,把它再次插入电脑,它就是一个上网卡。驱动程序可以选择让它工作于哪种配置,同一时间只能有一种配置有效。大多数的USB设备只有一种配置。
  3. 接口 (struct usb_interface):每个配置下可以有多个接口,这个接口不是硬件上的接口,可以把这个接口理解为功能,一个接口就代表该设备当前支持的一种功能。
  4. 端点 (struct usb_host_endpoint) :每个接口可以有多个端点。USB主机和设备就是通过端点进行数据交互的。每个端点地址对应一个方向,例如端点2-IN,端点2-OUT,这两个含义完全不同。

设备 (struct usb_device) 、配置 (struct usb_host_config) 、接口 (struct usb_interface)、 设置(struct usb_host_interface)、端点 (struct usb_host_endpoint) 之间的关系如下:

普通USB子设备(非集线器)struct usb_device 插入集线器 hub 端口后的处理过程如下:

普通USB子设备(非集线器)struct usb_device 插入集线器 hub 端口触发中断调用 hub_event ,并调用usb_get_device_descriptor() 读取USB子设备 struct usb_device 的设备描述符 struct usb_device_descriptor,并最终调用函数usb_alloc_dev()和usb_new_device() 创建USB子设备 struct usb_device ,usb_new_device() 创建USB子设备 struct usb_device 的最后一步调用 device_add() 在总线 struct bus_type usb_bus_type上寻找匹配的驱动 struct usb_device_driver usb_generic_driver,并执行 generic_probe()->usb_set_configuration(udev, c) 创建USB接口设备 struct usb_interface ,并再次调用 device_add() 在总线 struct bus_type usb_bus_type上寻找匹配的驱动 struct usb_device_driver :

  1. static void hub_event(struct work_struct *work)
  2. struct usb_hub *hub = container_of(work, struct usb_hub, events);
  3. struct usb_device *hdev = hub->hdev;
  4. struct device *hub_dev = hub->intfdev;
  5. struct usb_interface *intf = to_usb_interface(hub_dev);
  6. port_event(hub, i)->
  7. hub_port_status(hub, port1, &portstatus, &portchange);
  8. hub_port_connect_change(hub, port1, portstatus, portchange)->//处理端口改变的情况
  9. hub_port_connect(hub, port1, portstatus, portchange)->
  10. udev = usb_alloc_dev(hdev, hdev->bus, port1);
  11. status = hub_port_init(hub, udev, port1, i)->//初始化设备,设置地址,读取设备描述符
  12. //获取USB子设备描述符struct usb_device_descriptor
  13. usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);
  14. memcpy(&dev->descriptor, desc, size);
  15. /* Run it through the hoops (find a driver, etc) */
  16. status = usb_new_device(udev)->
  17. usb_enumerate_device(udev)-> /* Read descriptors */
  18. announce_device(udev)-> /* Tell the world! 告诉全世界我诞生了 */
  19. device_add(&udev->dev)->
  20. bus_probe_device(dev)->device_initial_probe(dev)->__device_attach()->
  21. return driver_probe_device(drv, dev)->
  22. static int generic_probe(struct usb_device *udev)->
  23. usb_choose_configuration(udev);
  24. usb_set_configuration(udev, c)->
  25. struct usb_interface *intf->dev.parent = &dev->dev;
  26. intf->dev.driver = NULL;
  27. intf->dev.bus = &usb_bus_type;
  28. intf->dev.type = &usb_if_device_type; //USB接口设备
  29. device_add(&intf->dev)

usb_new_device() 创建USB子设备 struct usb_device 的最后一步调用 device_add() 在总线 struct bus_type usb_bus_type上寻找匹配的的驱动 struct usb_driver:

  1. device_add(&udev->dev)->
  2. dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id);
  3. // 对于 USB2.0 的 root hub 实际打印:device: 'usb2': device_add
  4. pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
  5. error = bus_add_device(dev)->
  6. struct bus_type *bus = bus_get(dev->bus);
  7. //对于 usb-skeketon.c 驱动实际打印: bus: 'usb': add driver skeleton
  8. pr_debug("bus: '%s': add device %s\n", bus->name, dev_name(dev));
  9. error = sysfs_create_link(&dev->kobj, &dev->bus->p->subsys.kobj, "subsystem");
  10. klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);
  11. blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_ADD_DEVICE, dev);
  12. kobject_uevent(&dev->kobj, KOBJ_ADD);
  13. bus_probe_device(dev)->device_initial_probe(dev)->__device_attach(dev, true)->
  14. bus_for_each_drv(dev->bus, NULL, &data, _device_attach_driver)-> //在 USB 总线 struct bus_type usb_bus_type 上注册的驱动程序
  15. while ((drv = next_driver(&i)) && !error) //在 USB 总线 struct bus_type usb_bus_type 上注册的驱动程序
  16. {
  17. error = fn(drv, data)=_device_attach_driver;
  18. static int __device_attach_driver(struct device_driver *drv, void *_data)->
  19. if (!driver_match_device(drv, dev))-> //在 USB 总线 struct bus_type usb_bus_type 上匹配到驱动时返回值 为 1
  20. return drv->bus->match ? drv->bus->match(dev, drv) : 1;
  21. struct bus_type usb_bus_type.match = usb_device_match,
  22. // usb_device_match 有匹配的驱动时返回值为 1
  23. //在函数usb_alloc_dev() 中设置 dev->dev.type = &usb_device_type;
  24. static int usb_device_match(struct device *dev, struct device_driver *drv)
  25. {
  26. /* devices and interfaces are handled separately */
  27. //对于 usb子设备 ,is_usb_device(dev) 的返回值为 true
  28. //在函数usb_alloc_dev() 中设置 dev->dev.type = &usb_device_type;
  29. if (is_usb_device(dev)) //return dev->type == &usb_device_type;
  30. {
  31. /* interface drivers never match devices */
  32. //对于 USB通用驱动struct usb_device_driver usb_generic_driver, is_usb_device_driver() 返回值为1
  33. if (!is_usb_device_driver(drv))->
  34. return container_of(drv, struct usbdrv_wrap, driver)->for_devices;
  35. {
  36. return 0;
  37. }
  38. /* TODO: Add real matching code */
  39. return 1;
  40. }
  41. //在函数usb_set_configuration()中设置:intf->dev.type = &usb_if_device_type;
  42. else if (is_usb_interface(dev)) -> return dev->type == &usb_if_device_type; // 匹配USB接口设备的驱动
  43. {
  44. struct usb_interface *intf;
  45. struct usb_driver *usb_drv;
  46. const struct usb_device_id *id;
  47. /* device drivers never match interfaces */
  48. if (is_usb_device_driver(drv))
  49. return 0;
  50. intf = to_usb_interface(dev);
  51. usb_drv = to_usb_driver(drv);
  52. id = usb_match_id(intf, driver->id_table)->
  53. for (; id->idVendor || id->idProduct || id->bDeviceClass ||
  54. id->bInterfaceClass || id->driver_info; id++) {
  55. if (usb_match_one_id(interface, id))->
  56. intf = interface->cur_altsetting;
  57. dev = interface_to_usbdev(interface);
  58. if (!usb_match_device(dev, id))
  59. return 0;
  60. return usb_match_one_id_intf(dev, intf, id);
  61. {
  62. return id;
  63. }
  64. }
  65. if (id)
  66. return 1;
  67. id = usb_match_dynamic_id(intf, usb_drv);
  68. if (id)
  69. return 1;
  70. }
  71. return 0;
  72. }
  73. {
  74. return 0;
  75. }
  76. return driver_probe_device(drv, dev)-> //在 USB 总线 struct bus_type usb_bus_type 上匹配到驱动时执行到这里
  77. //对于 USB2.0 的 root hub 实际打印: bus: 'usb': driver_probe_device: matched device usb2 with driver usb
  78. pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
  79. drv->bus->name, __func__, dev_name(dev), drv->name);
  80. really_probe(dev, drv)->
  81. //对于 USB2.0 的 root hub 实际打印: bus: 'usb': driver_probe_device: matched device usb2 with driver usb
  82. pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
  83. drv->bus->name, __func__, drv->name, dev_name(dev));
  84. dev->driver = drv;
  85. // 所有USB子设备struct usb_device和USB接口设备struct usb_interface 都挂在USB总线上struct struct bus_type usb_bus_type
  86. if (dev->bus->probe) //struct struct bus_type usb_bus_type.probe = NULL
  87. {
  88. /*
  89. struct bus_type usb_bus_type = {
  90. .name = "usb",
  91. .match = usb_device_match,
  92. .uevent = usb_uevent,
  93. .need_parent_lock = true,
  94. };
  95. */
  96. ret = dev->bus->probe(dev);
  97. }
  98. else if (drv->probe) //USB接口子设备 struct usb_interface 驱动的情况
  99. {
  100. //对于驱动 struct usb_driver drv.drvwrap.driver.probe = usb_probe_interface
  101. //使用 usb_register() 或者 module_usb_driver()注册struct usb_driver drv,
  102. // 其struct usb_driver drv.drvwrap.driver.probe = usb_probe_interface
  103. ret = drv->probe(dev)=usb_probe_interface;
  104. static int usb_probe_interface(struct device *dev)->
  105. struct usb_device_id *id = usb_match_dynamic_id(intf, driver);
  106. if (!id)
  107. {
  108. id = usb_match_id(intf, driver->id_table)->
  109. for (; id->idVendor || id->idProduct || id->bDeviceClass ||
  110. id->bInterfaceClass || id->driver_info; id++) {
  111. if (usb_match_one_id(interface, id))->
  112. intf = interface->cur_altsetting;
  113. dev = interface_to_usbdev(interface);
  114. if (!usb_match_device(dev, id))
  115. return 0;
  116. return usb_match_one_id_intf(dev, intf, id);
  117. {
  118. return id;
  119. }
  120. }
  121. }
  122. dev_dbg(dev, "%s - got id\n", __func__);
  123. //对于 usb-skeletion.c 驱动 struct usb_driver skel_driver.probe = skel_probe
  124. //对于 usb serial 驱动,struct usb_driver usb_serial_driver.probe = usb_serial_probe
  125. driver->probe(intf, id);
  126. static int usb_serial_probe(struct usb_interface *interface, const struct usb_device_id *id)->
  127. type = search_serial_device(interface);
  128. serial = create_serial(dev, interface, type);
  129. iface_desc = interface->cur_altsetting;
  130. for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i)
  131. {
  132. endpoint = &iface_desc->endpoint[i].desc;
  133. if (usb_endpoint_is_bulk_in(endpoint)) {
  134. /* we found a bulk in endpoint */
  135. dev_dbg(ddev, "found bulk in on endpoint %d\n", i);
  136. if (num_bulk_in < MAX_NUM_PORTS) {
  137. bulk_in_endpoint[num_bulk_in] = endpoint;
  138. ++num_bulk_in;
  139. }
  140. }
  141. if (usb_endpoint_is_bulk_out(endpoint)) {
  142. /* we found a bulk out endpoint */
  143. dev_dbg(ddev, "found bulk out on endpoint %d\n", i);
  144. if (num_bulk_out < MAX_NUM_PORTS) {
  145. bulk_out_endpoint[num_bulk_out] = endpoint;
  146. ++num_bulk_out;
  147. }
  148. }
  149. if (usb_endpoint_is_int_in(endpoint)) {
  150. /* we found a interrupt in endpoint */
  151. dev_dbg(ddev, "found interrupt in on endpoint %d\n", i);
  152. if (num_interrupt_in < MAX_NUM_PORTS) {
  153. interrupt_in_endpoint[num_interrupt_in] =
  154. endpoint;
  155. ++num_interrupt_in;
  156. }
  157. }
  158. if (usb_endpoint_is_int_out(endpoint)) {
  159. /* we found an interrupt out endpoint */
  160. dev_dbg(ddev, "found interrupt out on endpoint %d\n", i);
  161. if (num_interrupt_out < MAX_NUM_PORTS) {
  162. interrupt_out_endpoint[num_interrupt_out] =
  163. endpoint;
  164. ++num_interrupt_out;
  165. }
  166. }
  167. }
  168. dev_info(ddev, "%s converter detected\n", type->description);
  169. for (i = 0; i < max_endpoints; ++i)
  170. {
  171. port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL);
  172. tty_port_init(&port->port);
  173. port->port.ops = &serial_port_ops;
  174. port->serial = serial;
  175. spin_lock_init(&port->lock);
  176. /* Keep this for private driver use for the moment but
  177. should probably go away */
  178. INIT_WORK(&port->work, usb_serial_port_work);
  179. serial->port[i] = port;
  180. port->dev.parent = &interface->dev;
  181. port->dev.driver = NULL;
  182. port->dev.bus = &usb_serial_bus_type;
  183. port->dev.release = &usb_serial_port_release;
  184. port->dev.groups = usb_serial_port_groups;
  185. device_initialize(&port->dev);
  186. }
  187. usb_set_intfdata(interface, serial);
  188. /* register all of the individual ports with the driver core */
  189. for (i = 0; i < num_ports; ++i)
  190. {
  191. port = serial->port[i];
  192. dev_set_name(&port->dev, "ttyUSB%d", port->minor); //对应设备 /dev/ttyUSB0
  193. dev_dbg(ddev, "registering %s\n", dev_name(&port->dev));
  194. device_enable_async_suspend(&port->dev);
  195. retval = device_add(&port->dev);
  196. }
  197. if (num_ports > 0)
  198. usb_serial_console_init(serial->port[0]->minor);

对于 usb-skeletion.c 驱动  struct usb_driver skel_driver.probe = skel_probe

  1. static int skel_probe(struct usb_interface *interface,
  2. const struct usb_device_id *id)->
  3. struct usb_skel *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  4. dev->udev = usb_get_dev(interface_to_usbdev(interface));
  5. retval = usb_get_device_descriptor(dev->udev, USB_DT_DEVICE_SIZE);
  6. iface_desc = interface->cur_altsetting;
  7. for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
  8. endpoint = &iface_desc->endpoint[i].desc;
  9. /* we found a bulk in endpoint */
  10. buffer_size = usb_endpoint_maxp(endpoint);
  11. dev->bulk_in_size = buffer_size;
  12. dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
  13. dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
  14. dev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL);
  15. }
  16. usb_set_intfdata(interface, dev);
  17. usb_register_dev(interface, &skel_class)->
  18. init_usb_class();
  19. intf->usb_dev = device_create(usb_class->class, &intf->dev,
  20. MKDEV(USB_MAJOR, minor), class_driver,
  21. "%s", temp);
  22. dev_info(&interface->dev,
  23. "USB Skeleton device now attached to USBSkel-%d",
  24. interface->minor);

 

 

 

 

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/614026
推荐阅读
相关标签
  

闽ICP备14008679号