本文简单介绍一下usb hub驱动如何工作。
通过前面文章我们知道,usb控制器驱动注册时会注册一个root_hub对应的usb_interface设备,它对于的驱动就在drivers/usb/core/hub.c里面, 当hub设备被注册时,会匹配到这个驱动,开始执行hub_probe。我们还是不会关注太多细节,主要关注hub是如何发现并创建一个设备的。
hub_probe里主要就是分配了一个usb_hub结构,并且注册了一个events工作队列和一个rq_urb_retry定时器,events工作队列主要用来处理hub的一些插拔事件,rq_urb_retry用来向hub发送hub->urb失败后通过定时器回调重新发送。然后调用hub_configure。
1777 static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
1778 {
1779 struct usb_host_interface *desc;
1780 struct usb_device *hdev;
1781 struct usb_hub *hub;
1782
1783 desc = intf->cur_altsetting;
1784 hdev = interface_to_usbdev(intf);
1785
1786 /*
1787 * Set default autosuspend delay as 0 to speedup bus suspend,
1788 * based on the below considerations:
1789 *
1790 * - Unlike other drivers, the hub driver does not rely on the
1791 * autosuspend delay to provide enough time to handle a wakeup
1792 * event, and the submitted status URB is just to check future
1793 * change on hub downstream ports, so it is safe to do it.
1794 *
1795 * - The patch might cause one or more auto supend/resume for
1796 * below very rare devices when they are plugged into hub
1797 * first time:
1798 *
1799 * devices having trouble initializing, and disconnect
1800 * themselves from the bus and then reconnect a second
1801 * or so later
1802 *
1803 * devices just for downloading firmware, and disconnects
1804 * themselves after completing it
1805 *
1806 * For these quite rare devices, their drivers may change the
1807 * autosuspend delay of their parent hub in the probe() to one
1808 * appropriate value to avoid the subtle problem if someone
1809 * does care it.
1810 *
1811 * - The patch may cause one or more auto suspend/resume on
1812 * hub during running 'lsusb', but it is probably too
1813 * infrequent to worry about.
1814 *
1815 * - Change autosuspend delay of hub can avoid unnecessary auto
1816 * suspend timer for hub, also may decrease power consumption
1817 * of USB bus.
1818 *
1819 * - If user has indicated to prevent autosuspend by passing
1820 * usbcore.autosuspend = -1 then keep autosuspend disabled.
1821 */
1822 #ifdef CONFIG_PM
1823 if (hdev->dev.power.autosuspend_delay >= 0)
1824 pm_runtime_set_autosuspend_delay(&hdev->dev, 0);
1825 #endif
1826
1827 /*
1828 * Hubs have proper suspend/resume support, except for root hubs
1829 * where the controller driver doesn't have bus_suspend and
1830 * bus_resume methods.
1831 */
1832 if (hdev->parent) { /* normal device */
1833 usb_enable_autosuspend(hdev);
1834 } else { /* root hub */
1835 const struct hc_driver *drv = bus_to_hcd(hdev->bus)->driver;
1836
1837 if (drv->bus_suspend && drv->bus_resume)
1838 usb_enable_autosuspend(hdev);
1839 }
1840
1841 if (hdev->level == MAX_TOPO_LEVEL) {
1842 dev_err(&intf->dev,
1843 "Unsupported bus topology: hub nested too deep\n");
1844 return -E2BIG;
1845 }
1846
1847 #ifdef CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB
1848 if (hdev->parent) {
1849 dev_warn(&intf->dev, "ignoring external hub\n");
1850 return -ENODEV;
1851 }
1852 #endif
1853
1854 if (!hub_descriptor_is_sane(desc)) {
1855 dev_err(&intf->dev, "bad descriptor, ignoring hub\n");
1856 return -EIO;
1857 }
1858
1859 /* We found a hub */
1860 dev_info(&intf->dev, "USB hub found\n");
1861
1862 hub = kzalloc(sizeof(*hub), GFP_KERNEL);
1863 if (!hub)
1864 return -ENOMEM;
1865
1866 kref_init(&hub->kref);
1867 hub->intfdev = &intf->dev;
1868 hub->hdev = hdev;
1869 INIT_DELAYED_WORK(&hub->leds, led_work);
1870 INIT_DELAYED_WORK(&hub->init_work, NULL);
1871 INIT_WORK(&hub->events, hub_event);
1872 spin_lock_init(&hub->irq_urb_lock);
1873 timer_setup(&hub->irq_urb_retry, hub_retry_irq_urb, 0);
1874 usb_get_intf(intf);
1875 usb_get_dev(hdev);
1876
1877 usb_set_intfdata(intf, hub);
1878 intf->needs_remote_wakeup = 1;
1879 pm_suspend_ignore_children(&intf->dev, true);
1880
1881 if (hdev->speed == USB_SPEED_HIGH)
1882 highspeed_hubs++;
1883
1884 if (id->driver_info & HUB_QUIRK_CHECK_PORT_AUTOSUSPEND)
1885 hub->quirk_check_port_auto_suspend = 1;
1886
1887 if (id->driver_info & HUB_QUIRK_DISABLE_AUTOSUSPEND) {
1888 hub->quirk_disable_autosuspend = 1;
1889 usb_autopm_get_interface_no_resume(intf);
1890 }
1891
1892 if (hub_configure(hub, &desc->endpoint[0].desc) >= 0)
1893 return 0;
1894
1895 hub_disconnect(intf);
1896 return -ENODEV;
1897 }
1898
1899 static int
1900 hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
1901 {
1902 struct usb_device *hdev = interface_to_usbdev(intf);
1903 struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
1904
1905 /* assert ifno == 0 (part of hub spec) */
1906 switch (code) {
1907 case USBDEVFS_HUB_PORTINFO: {
1908 struct usbdevfs_hub_portinfo *info = user_data;
1909 int i;
1910
1911 spin_lock_irq(&device_state_lock);
1912 if (hdev->devnum <= 0)
1913 info->nports = 0;
1914 else {
1915 info->nports = hdev->maxchild;
1916 for (i = 0; i < info->nports; i++) {
1917 if (hub->ports[i]->child == NULL)
1918 info->port[i] = 0;
1919 else
1920 info->port[i] =
1921 hub->ports[i]->child->devnum;
1922 }
1923 }
1924 spin_unlock_irq(&device_state_lock);
1925
1926 return info->nports + 1;
1927 }
1928
1929 default:
1930 return -ENOSYS;
1931 }
1932 }
hub_configure中会读取全部的hub描述符信息,用来初始化usb_hub,并且会填充hub->urb,这个urb就是用来轮询hub状态的urb,它的回调函数就是hub_irq。然后调用hub_activate。
1373 static int hub_configure(struct usb_hub *hub,
1374 struct usb_endpoint_descriptor *endpoint)
1375 {
1376 struct usb_hcd *hcd;
1377 struct usb_device *hdev = hub->hdev;
1378 struct device *hub_dev = hub->intfdev;
1379 u16 hubstatus, hubchange;
1380 u16 wHubCharacteristics;
1381 unsigned int pipe;
1382 int maxp, ret, i;
1383 char *message = "out of memory";
1384 unsigned unit_load;
1385 unsigned full_load;
1386 unsigned maxchild;
1387
1388 hub->buffer = kmalloc(sizeof(*hub->buffer), GFP_KERNEL);
1389 if (!hub->buffer) {
1390 ret = -ENOMEM;
1391 goto fail;
1392 }
1393
1394 hub->status = kmalloc(sizeof(*hub->status), GFP_KERNEL);
1395 if (!hub->status) {
1396 ret = -ENOMEM;
1397 goto fail;
1398 }
1399 mutex_init(&hub->status_mutex);
1400
1401 hub->descriptor = kzalloc(sizeof(*hub->descriptor), GFP_KERNEL);
1402 if (!hub->descriptor) {
1403 ret = -ENOMEM;
1404 goto fail;
1405 }
1406
1407 /* Request the entire hub descriptor.
1408 * hub->descriptor can handle USB_MAXCHILDREN ports,
1409 * but a (non-SS) hub can/will return fewer bytes here.
1410 */
1411 ret = get_hub_descriptor(hdev, hub->descriptor);
1412 if (ret < 0) {
1413 message = "can't read hub descriptor";
1414 goto fail;
1415 }
1416
1417 maxchild = USB_MAXCHILDREN;
1418 if (hub_is_superspeed(hdev))
1419 maxchild = min_t(unsigned, maxchild, USB_SS_MAXPORTS);
1420
1421 if (hub->descriptor->bNbrPorts > maxchild) {
1422 message = "hub has too many ports!";
1423 ret = -ENODEV;
1424 goto fail;
1425 } else if