Subject: [PATCH] usb: xhci: Fix bNbrPorts and wHubCharacteristics  overwritten 
by another controller

For the `struct descriptor`, only the `hub` part (`bNbrPorts` and 
`wHubCharacteristics`) is different for each controller, the other five members 
(device, config, interface, endpoint,ep_companion)are identical for all XHCI 
root hubs.

Signed-off-by: Beibei Yang <[email protected]>

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index dbeb88a..1469b3d 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -942,7 +942,7 @@ static int xhci_submit_root(struct usb_device *udev, 
unsigned long pipe,
                case USB_DT_HUB:
                case USB_DT_SS_HUB:
                        debug("USB_DT_HUB config\n");
-                       srcptr = &descriptor.hub;
+                       srcptr = &ctrl->hub_desc;
                        srclen = 0x8;
                        break;
                default:
@@ -1203,19 +1203,21 @@ static int xhci_lowlevel_init(struct xhci_ctrl *ctrl)
                return -ENOMEM;
 
        reg = xhci_readl(&hccr->cr_hcsparams1);
-       descriptor.hub.bNbrPorts = HCS_MAX_PORTS(reg);
-       printf("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts);
+       ctrl->hub_desc = descriptor.hub;
+       ctrl->hub_desc.bNbrPorts = ((reg & HCS_MAX_PORTS_MASK) >>
+               HCS_MAX_PORTS_SHIFT);
+       printf("Register %x NbrPorts %d\n", reg, ctrl->hub_desc.bNbrPorts);
 
        /* Port Indicators */
        reg = xhci_readl(&hccr->cr_hccparams);
        if (HCS_INDICATOR(reg))
-               put_unaligned(get_unaligned(&descriptor.hub.wHubCharacteristics)
-                               | 0x80, &descriptor.hub.wHubCharacteristics);
+               put_unaligned(get_unaligned(&ctrl->hub_desc.wHubCharacteristics)
+                               | 0x80, &ctrl->hub_desc.wHubCharacteristics);
 
        /* Port Power Control */
        if (HCC_PPC(reg))
-               put_unaligned(get_unaligned(&descriptor.hub.wHubCharacteristics)
-                               | 0x01, &descriptor.hub.wHubCharacteristics);
+               put_unaligned(get_unaligned(&ctrl->hub_desc.wHubCharacteristics)
+                               | 0x01, &ctrl->hub_desc.wHubCharacteristics);
 
        if (xhci_start(hcor)) {
                xhci_reset(hcor);
diff --git a/include/usb/xhci.h b/include/usb/xhci.h
index ea4cf3f..9feb3aa 100644
--- a/include/usb/xhci.h
+++ b/include/usb/xhci.h
@@ -22,6 +22,7 @@
 #include <asm/io.h>
 #include <linux/list.h>
 #include <linux/compat.h>
+#include <usb.h>
 
 #define MAX_EP_CTX_NUM         31
 #define XHCI_ALIGNMENT         64
@@ -1214,6 +1215,7 @@ struct xhci_ctrl {
        struct xhci_erst_entry entry[ERST_NUM_SEGS];
        struct xhci_scratchpad *scratchpad;
        struct xhci_virt_device *devs[MAX_HC_SLOTS];
+       struct usb_hub_descriptor hub_desc;
        int rootdev;
        u16 hci_version;
        u32 quirks;

Reply via email to