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 <st...@rowland.harvard.edu>
> Signed-off-by: Lan Tianyu <tianyu....@intel.com>
> ---
>  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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to