Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: Use hub port data to determine whether a port is removable

Hubs have a flag to indicate whether a given port carries removable devices
or not. This is not strictly accurate in that some built-in devices
will be flagged as removable, but followup patches will make use of platform
data to make this more reliable.

Signed-off-by: Matthew Garrett <mjg@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Matthew Garrett and committed by
Greg Kroah-Hartman
d35e70d5 0846e7e9

+40
+40
drivers/usb/core/hub.c
··· 1838 1838 return err; 1839 1839 } 1840 1840 1841 + static void set_usb_port_removable(struct usb_device *udev) 1842 + { 1843 + struct usb_device *hdev = udev->parent; 1844 + struct usb_hub *hub; 1845 + u8 port = udev->portnum; 1846 + u16 wHubCharacteristics; 1847 + bool removable = true; 1848 + 1849 + if (!hdev) 1850 + return; 1851 + 1852 + hub = hdev_to_hub(udev->parent); 1853 + 1854 + wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); 1855 + 1856 + if (!(wHubCharacteristics & HUB_CHAR_COMPOUND)) 1857 + return; 1858 + 1859 + if (hub_is_superspeed(hdev)) { 1860 + if (hub->descriptor->u.ss.DeviceRemovable & (1 << port)) 1861 + removable = false; 1862 + } else { 1863 + if (hub->descriptor->u.hs.DeviceRemovable[port / 8] & (1 << (port % 8))) 1864 + removable = false; 1865 + } 1866 + 1867 + if (removable) 1868 + udev->removable = USB_DEVICE_REMOVABLE; 1869 + else 1870 + udev->removable = USB_DEVICE_FIXED; 1871 + } 1841 1872 1842 1873 /** 1843 1874 * usb_new_device - perform initial device setup (usbcore-internal) ··· 1927 1896 announce_device(udev); 1928 1897 1929 1898 device_enable_async_suspend(&udev->dev); 1899 + 1900 + /* 1901 + * check whether the hub marks this port as non-removable. Do it 1902 + * now so that platform-specific data can override it in 1903 + * device_add() 1904 + */ 1905 + if (udev->parent) 1906 + set_usb_port_removable(udev); 1907 + 1930 1908 /* Register the device. The device driver is responsible 1931 1909 * for configuring the device and invoking the add-device 1932 1910 * notifier chain (used by usbfs and possibly others).