On Sun, Jan 20, 2013 at 01:53:31AM +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. > > Acked-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> > Signed-off-by: Lan Tianyu <tianyu.lan@xxxxxxxxx> > --- > drivers/usb/core/hcd.c | 4 ++++ > drivers/usb/core/hub.c | 43 +++++++++++++++++++++++++++++++++++++++++++ > drivers/usb/core/usb.h | 3 +++ > 3 files changed, 50 insertions(+) > > diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c > index 5f6da8b..2459896 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 f6ff130..f7e1402 100644 > --- a/drivers/usb/core/hub.c > +++ b/drivers/usb/core/hub.c > @@ -1513,6 +1513,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; > > @@ -5193,6 +5195,47 @@ 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); > + } > +} > + > #ifdef CONFIG_ACPI > /** > * usb_get_hub_port_acpi_handle - Get the usb port's acpi handle > diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h > index fb7d8fc..31f32cd 100644 > --- a/drivers/usb/core/usb.h > +++ b/drivers/usb/core/usb.h > @@ -1,5 +1,6 @@ > #include <linux/pm.h> > #include <linux/acpi.h> > +#include <linux/usb/ch11.h> Minor nit, I hate having .h files include other .h files. Please just predefine the structure you need here, instead of including the .h file. 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