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

usb: cleanup setting udev->removable from port_dev->connect_type

Once usb-acpi has set the port's connect type the usb_device's
->removable attribute can be set in the standard location
set_usb_port_removable().

This also changes behavior in the case where the firmware says that the
port connect type is unknown. In that case just use the default setting
determined from the hub descriptor.

Note, we no longer pass udev->portnum to acpi_find_child_device() in the
root hub case since:
1/ the usb-core sets this to zero
2/ acpi always expects zero
...just pass zero.

Suggested-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Dan Williams and committed by
Greg Kroah-Hartman
a4204ff0 d99f6b41

+23 -33
+17 -5
drivers/usb/core/hub.c
··· 2305 2305 udev->removable = USB_DEVICE_REMOVABLE; 2306 2306 else 2307 2307 udev->removable = USB_DEVICE_FIXED; 2308 + 2309 + /* 2310 + * Platform firmware may have populated an alternative value for 2311 + * removable. If the parent port has a known connect_type use 2312 + * that instead. 2313 + */ 2314 + switch (hub->ports[udev->portnum - 1]->connect_type) { 2315 + case USB_PORT_CONNECT_TYPE_HOT_PLUG: 2316 + udev->removable = USB_DEVICE_REMOVABLE; 2317 + break; 2318 + case USB_PORT_CONNECT_TYPE_HARD_WIRED: 2319 + udev->removable = USB_DEVICE_FIXED; 2320 + break; 2321 + default: /* use what was set above */ 2322 + break; 2323 + } 2308 2324 } 2309 2325 2310 2326 /** ··· 2390 2374 2391 2375 device_enable_async_suspend(&udev->dev); 2392 2376 2393 - /* 2394 - * check whether the hub marks this port as non-removable. Do it 2395 - * now so that platform-specific data can override it in 2396 - * device_add() 2397 - */ 2377 + /* check whether the hub or firmware marks this port as non-removable */ 2398 2378 if (udev->parent) 2399 2379 set_usb_port_removable(udev); 2400 2380
+6 -28
drivers/usb/core/usb-acpi.c
··· 136 136 137 137 static struct acpi_device *usb_acpi_find_companion(struct device *dev) 138 138 { 139 - int port1; 140 139 struct usb_device *udev; 140 + struct acpi_device *adev; 141 141 acpi_handle *parent_handle; 142 142 143 143 /* ··· 155 155 */ 156 156 if (is_usb_device(dev)) { 157 157 udev = to_usb_device(dev); 158 - port1 = udev->portnum; 159 - if (udev->parent) { 160 - struct usb_hub *hub; 161 - 162 - hub = usb_hub_to_struct_hub(udev->parent); 163 - /* 164 - * According usb port's connect type to set usb device's 165 - * removability. 166 - */ 167 - switch (hub->ports[port1 - 1]->connect_type) { 168 - case USB_PORT_CONNECT_TYPE_HOT_PLUG: 169 - udev->removable = USB_DEVICE_REMOVABLE; 170 - break; 171 - case USB_PORT_CONNECT_TYPE_HARD_WIRED: 172 - udev->removable = USB_DEVICE_FIXED; 173 - break; 174 - default: 175 - udev->removable = USB_DEVICE_REMOVABLE_UNKNOWN; 176 - break; 177 - } 178 - 158 + if (udev->parent) 179 159 return NULL; 180 - } 181 160 182 - /* root hub's parent is the usb hcd. */ 183 - return acpi_find_child_device(ACPI_COMPANION(dev->parent), 184 - port1, false); 161 + /* root hub is only child (_ADR=0) under its parent, the HC */ 162 + adev = ACPI_COMPANION(dev->parent); 163 + return acpi_find_child_device(adev, 0, false); 185 164 } else if (is_usb_port(dev)) { 186 165 struct usb_port *port_dev = to_usb_port(dev); 187 - struct acpi_device *adev = NULL; 166 + int port1 = port_dev->portnum; 188 167 189 168 /* Get the struct usb_device point of port's hub */ 190 169 udev = to_usb_device(dev->parent->parent); 191 - port1 = port_dev->portnum; 192 170 193 171 /* 194 172 * The root hub ports' parent is the root hub. The non-root-hub