On Fri, Jan 11, 2013 at 08:10:39PM +0800, Lan Tianyu wrote: > ACPI provide "_PLD" and "_UPC" aml methods to describe usb port > visibility and connectability. This patch is to add usb_hub_adjust_DeviceRemovable() > to adjust usb hub port's DeviceRemovable according ACPI information and invoke it in > the rh_call_control(). When hub descriptor request is issued at first time, > usb port device isn't created and usb port is not bound with acpi. So first > hub descriptor request is not changed based on ACPI information. After usb > port devices being created, call usb_hub_adjust_DeviceRemovable in the hub_configure() > and then set hub port's DeviceRemovable according ACPI information and this also works > for non-root hub. > > Signed-off-by: Lan Tianyu <tianyu.lan@xxxxxxxxx> > --- > drivers/usb/core/hcd.c | 4 ++++ > drivers/usb/core/hub.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ > drivers/usb/core/usb.h | 3 +++ > 3 files changed, 55 insertions(+) > > diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c > index 4225d5e..6687302 100644 > --- a/drivers/usb/core/hcd.c > +++ b/drivers/usb/core/hcd.c > @@ -619,6 +619,10 @@ nongeneric: > status = hcd->driver->hub_control (hcd, > typeReq, wValue, wIndex, > tbuf, wLength); > + > + if (typeReq == GetHubDescriptor) > + usb_hub_adjust_deviceremovable(hcd->self.root_hub, > + (struct usb_hub_descriptor *)tbuf); > break; > error: > /* "protocol stall" on error */ > diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c > index f5caf72..7a893b0 100644 > --- a/drivers/usb/core/hub.c > +++ b/drivers/usb/core/hub.c > @@ -1500,6 +1500,8 @@ static int hub_configure(struct usb_hub *hub, > dev_err(hub->intfdev, > "couldn't create port%d device.\n", i + 1); > > + usb_hub_adjust_deviceremovable(hdev, hub->descriptor); > + > hub_activate(hub, HUB_INIT); > return 0; > > @@ -5162,6 +5164,52 @@ usb_get_hub_port_connect_type(struct usb_device *hdev, int port1) > return hub->ports[port1 - 1]->connect_type; > } > > +void usb_hub_adjust_deviceremovable(struct usb_device *hdev, > + struct usb_hub_descriptor *desc) > +{ > + enum usb_port_connect_type connect_type; > + int i; > + > + if (!hub_is_superspeed(hdev)) { > + for (i = 1; i <= hdev->maxchild; i++) { > + connect_type = > + usb_get_hub_port_connect_type(hdev, i); > + > + if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) { > + u8 mask = 1 << (i%8); > + > + if (!(desc->u.hs.DeviceRemovable[i/8] & mask)) { > + dev_dbg(&hdev->dev, "usb port%d's DeviceRemovable is changed to 1 according to platform information.\n", > + i); > + desc->u.hs.DeviceRemovable[i/8] |= mask; > + } > + } > + } > + } else { > + u16 port_removable = > + le16_to_cpu(desc->u.ss.DeviceRemovable); > + > + for (i = 1; i <= hdev->maxchild; i++) { > + connect_type = usb_get_hub_port_connect_type(hdev, i); > + > + if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) { > + u16 mask = 1 << i; > + > + if (!(port_removable & mask)) { > + dev_dbg(&hdev->dev, "usb port%d's DeviceRemovable is changed to 1 according to platform information.\n", > + i); > + port_removable |= mask; > + } > + } > + } > + > + desc->u.ss.DeviceRemovable = cpu_to_le16(port_removable); > + } > +} Ugh, the formatting of that function is horrible. You have line-breaks all over the place where you don't need them at all, making it almost impossible to read this. Please redo it so it can be read better. thanks, greg k-h -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html