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函数结束。