USB hub 分析

来源:互联网 发布:阿里云升级配置 编辑:程序博客网 时间:2024/04/29 08:12

HUB的驱动注册
static int __init usb_init(void)中调用 retval = usb_hub_init();

int usb_hub_init(void)
{
向USB总线注册HUB的驱动程序
 if (usb_register(&hub_driver) < 0) {
  printk(KERN_ERR "%s: can't register hub driver\n",
   usbcore_name);
  return -1;
 }
创建HUB事件处理线程,
 khubd_task = kthread_run(hub_thread, NULL, "khubd");
 if (!IS_ERR(khubd_task))
  return 0;

 /* Fall through if kernel_thread failed */
 usb_deregister(&hub_driver);
 printk(KERN_ERR "%s: can't start khubd\n", usbcore_name);

 return -1;
}

HUB设备的初始化和注册
主要是在usb_hcd_pci_probe-》usb_add_hcd函数中

分配HUB的usb_device
 if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) {
  dev_err(hcd->self.controller, "unable to allocate root hub\n");
  retval = -ENOMEM;
  goto err_allocate_root_hub;
 }
 hcd->self.root_hub = rhdev;
设置HUB的速度
 switch (hcd->driver->flags & HCD_MASK) {
 case HCD_USB11:
  rhdev->speed = USB_SPEED_FULL;
  break;
 case HCD_USB2:
  rhdev->speed = USB_SPEED_HIGH;
  break;
 case HCD_USB3:
  rhdev->speed = USB_SPEED_SUPER;
  break;
 default:
  goto err_set_rh_speed;
 }
初始化电源管理部分。
 device_init_wakeup(&rhdev->dev, 1);
设置HUB电流
 rhdev->bus_mA = min(500u, hcd->power_budget);
 
然后就是register_root_hub函数了:
 struct device *parent_dev = hcd->self.controller;
 struct usb_device *usb_dev = hcd->self.root_hub;
 const int devnum = 1;
 int retval;
root HUB的设备号直接设置为1,root HUB比较特殊。
 usb_dev->devnum = devnum;
总线使用的下一个设备号,从2开始
 usb_dev->bus->devnum_next = devnum + 1;
 memset (&usb_dev->bus->devmap.devicemap, 0,
   sizeof usb_dev->bus->devmap.devicemap);
在总线的devicemap中置位表示该设备号已被分配
 set_bit (devnum, usb_dev->bus->devmap.devicemap);
root hub比较特殊直接进入地址状态。
 usb_set_device_state(usb_dev, USB_STATE_ADDRESS);、
 
 mutex_lock(&usb_bus_list_lock);
获取设备描述符
 usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
 retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
 if (retval != sizeof usb_dev->descriptor) {
  mutex_unlock(&usb_bus_list_lock);
  dev_dbg (parent_dev, "can't read %s device descriptor %d\n",
    dev_name(&usb_dev->dev), retval);
  return (retval < 0) ? retval : -EMSGSIZE;
 }
注册设备
 retval = usb_new_device (usb_dev);
 if (retval) {
  dev_err (parent_dev, "can't register root hub for %s, %d\n",
    dev_name(&usb_dev->dev), retval);
 }
 mutex_unlock(&usb_bus_list_lock);

 if (retval == 0) {
  spin_lock_irq (&hcd_root_hub_lock);
  hcd->rh_registered = 1;
  spin_unlock_irq (&hcd_root_hub_lock);

  /* Did the HC die before the root hub was registered? */
  if (HCD_DEAD(hcd))
   usb_hc_died (hcd); /* This time clean up */
 }

 return retval;
register_root_hub函数结束。