On 2012年11月29日 08:08, Alan Stern wrote:
> On Wed, 28 Nov 2012, Sarah Sharp wrote:
>
>>>> The shared code to overwrite the bits should probably print a warning if
>>>> the host and ACPI bits differ.
>>>
>>> I'm not so sure about that. For one thing, who wants warnings to be
>>> logged every time they run "lsusb -v"?
>>
>> Yeah, that's probably not a great idea.
>>
>>> Also, this sort of thing might be more common than you might expect.
>>> I'd guess that if the ACPI information contains anything useful at all,
>>> it will be different from the [Ex]HCI information.
>>>
>>> Tianyu's patches log such warnings for xHCI but not for EHCI. That
>>> inconsistency is another reason to rework them.
>>
>> Tianyu did that because I asked him to for xHCI. I didn't think about
>> the lsusb implications. You're right that it will probably be annoying
>> to the user, so he should just drop the warning in the shared code.
>
> It could be changed to a dev_dbg. That wouldn't bother people and it
> might be useful.
>
> Alan Stern
>
Hi Alan:
how about following patch?
Index: usb/drivers/usb/core/hub.c
===================================================================
--- usb.orig/drivers/usb/core/hub.c
+++ usb/drivers/usb/core/hub.c
@@ -1441,6 +1441,8 @@ static int hub_configure(struct usb_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;
@@ -5086,8 +5088,56 @@ usb_get_hub_port_connect_type(struct usb
{
struct usb_hub *hub = hdev_to_hub(hdev);
+ if (!hub)
+ return USB_PORT_CONNECT_TYPE_UNKNOWN;
+
return hub->ports[port1 - 1]->connect_type;
}
+EXPORT_SYMBOL_GPL(usb_get_hub_port_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, "usb2.0
port%d's DeviceRemovable is changed to 1 according 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, "usb3.0
port%d's DeviceRemovable is changed to 1 according platform
information.\n", i);
+
+ port_removable |= mask;
+ }
+ }
+
+ desc->u.ss.DeviceRemovable =
+ cpu_to_le16(port_removable);
+ }
+}
#ifdef CONFIG_ACPI
/**
Index: usb/drivers/usb/core/usb.h
===================================================================
--- usb.orig/drivers/usb/core/usb.h
+++ usb/drivers/usb/core/usb.h
@@ -1,5 +1,6 @@
#include <linux/pm.h>
#include <linux/acpi.h>
+#include <linux/usb/ch11.h>
struct dev_state;
@@ -169,10 +170,13 @@ extern void usb_notify_add_device(struct
extern void usb_notify_remove_device(struct usb_device *udev);
extern void usb_notify_add_bus(struct usb_bus *ubus);
extern void usb_notify_remove_bus(struct usb_bus *ubus);
+
extern enum usb_port_connect_type
usb_get_hub_port_connect_type(struct usb_device *hdev, int port1);
extern void usb_set_hub_port_connect_type(struct usb_device *hdev, int
port1,
enum usb_port_connect_type type);
+extern void usb_hub_adjust_DeviceRemovable(struct usb_device *hdev,
+ struct usb_hub_descriptor *desc);
#ifdef CONFIG_ACPI
extern int usb_acpi_register(void);
Index: usb/drivers/usb/core/hcd.c
===================================================================
--- usb.orig/drivers/usb/core/hcd.c
+++ usb/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 */
--
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html