A number of platforms have differences in the way the NDP register (in
roothub_a) reports the number of ports present. This patch allows the
platform specific code to optionally supply the number of ports. The
driver just reads the value at init (if not supplied) instead of reading
it every time its needed.

It also sets the value correctly for the ARM pxa27x architecture.

Signed-Off-By: Richard Purdie <[EMAIL PROTECTED]>

Index: linux-2.6.12/drivers/usb/host/ohci-dbg.c
===================================================================
--- linux-2.6.12.orig/drivers/usb/host/ohci-dbg.c       2005-08-25 
15:53:19.000000000 +0100
+++ linux-2.6.12/drivers/usb/host/ohci-dbg.c    2005-08-25 15:55:38.000000000 
+0100
@@ -228,23 +228,22 @@
        char **next,
        unsigned *size)
 {
-       u32                     temp, ndp, i;
+       u32                     temp, i;
 
        temp = roothub_a (controller);
        if (temp == ~(u32)0)
                return;
-       ndp = (temp & RH_A_NDP);
 
        if (verbose) {
                ohci_dbg_sw (controller, next, size,
-                       "roothub.a %08x POTPGT=%d%s%s%s%s%s NDP=%d\n", temp,
+                       "roothub.a %08x POTPGT=%d%s%s%s%s%s NDP=%d(%d)\n", temp,
                        ((temp & RH_A_POTPGT) >> 24) & 0xff,
                        (temp & RH_A_NOCP) ? " NOCP" : "",
                        (temp & RH_A_OCPM) ? " OCPM" : "",
                        (temp & RH_A_DT) ? " DT" : "",
                        (temp & RH_A_NPS) ? " NPS" : "",
                        (temp & RH_A_PSM) ? " PSM" : "",
-                       ndp
+                       (temp & RH_A_NDP), controller->num_ports
                        );
                temp = roothub_b (controller);
                ohci_dbg_sw (controller, next, size,
@@ -266,7 +265,7 @@
                        );
        }
 
-       for (i = 0; i < ndp; i++) {
+       for (i = 0; i < controller->num_ports; i++) {
                temp = roothub_portstatus (controller, i);
                dbg_port_sw (controller, i, temp, next, size);
        }
Index: linux-2.6.12/drivers/usb/host/ohci-hcd.c
===================================================================
--- linux-2.6.12.orig/drivers/usb/host/ohci-hcd.c       2005-08-25 
15:53:19.000000000 +0100
+++ linux-2.6.12/drivers/usb/host/ohci-hcd.c    2005-08-25 15:55:38.000000000 
+0100
@@ -485,6 +485,10 @@
        // flush the writes
        (void) ohci_readl (ohci, &ohci->regs->control);
 
+       /* Read the number of ports unless overridden */
+       if (ohci->num_ports == 0)
+               ohci->num_ports = roothub_a(ohci) & RH_A_NDP;
+
        if (ohci->hcca)
                return 0;
 
@@ -561,10 +565,8 @@
        msleep(temp);
        temp = roothub_a (ohci);
        if (!(temp & RH_A_NPS)) {
-               unsigned ports = temp & RH_A_NDP; 
-
                /* power down each port */
-               for (temp = 0; temp < ports; temp++)
+               for (temp = 0; temp < ohci->num_ports; temp++)
                        ohci_writel (ohci, RH_PS_LSDA,
                                &ohci->regs->roothub.portstatus [temp]);
        }
@@ -861,7 +863,7 @@
                 * and that if we try to turn them back on the root hub
                 * will respond to CSC processing.
                 */
-               i = roothub_a (ohci) & RH_A_NDP;
+               i = ohci->num_ports;
                while (i--)
                        ohci_writel (ohci, RH_PS_PSS,
                                &ohci->regs->roothub.portstatus [temp]);
Index: linux-2.6.12/drivers/usb/host/ohci-hub.c
===================================================================
--- linux-2.6.12.orig/drivers/usb/host/ohci-hub.c       2005-08-25 
15:53:19.000000000 +0100
+++ linux-2.6.12/drivers/usb/host/ohci-hub.c    2005-08-25 15:55:38.000000000 
+0100
@@ -184,7 +184,7 @@
        if (status != -EINPROGRESS)
                return status;
 
-       temp = roothub_a (ohci) & RH_A_NDP;
+       temp = ohci->num_ports;
        enables = 0;
        while (temp--) {
                u32 stat = ohci_readl (ohci,
@@ -304,7 +304,7 @@
 ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
 {
        struct ohci_hcd *ohci = hcd_to_ohci (hcd);
-       int             ports, i, changed = 0, length = 1;
+       int             i, changed = 0, length = 1;
        int             can_suspend = hcd->can_wakeup;
        unsigned long   flags;
 
@@ -319,26 +319,18 @@
                goto done;
        }
 
-       ports = roothub_a (ohci) & RH_A_NDP; 
-       if (ports > MAX_ROOT_PORTS) {
-               ohci_err (ohci, "bogus NDP=%d, rereads as NDP=%d\n", ports,
-                         ohci_readl (ohci, &ohci->regs->roothub.a) & RH_A_NDP);
-               /* retry later; "should not happen" */
-               goto done;
-       }
-
        /* init status */
        if (roothub_status (ohci) & (RH_HS_LPSC | RH_HS_OCIC))
                buf [0] = changed = 1;
        else
                buf [0] = 0;
-       if (ports > 7) {
+       if (ohci->num_ports > 7) {
                buf [1] = 0;
                length++;
        }
 
        /* look at each port */
-       for (i = 0; i < ports; i++) {
+       for (i = 0; i < ohci->num_ports; i++) {
                u32     status = roothub_portstatus (ohci, i);
 
                if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
@@ -395,15 +387,14 @@
        struct usb_hub_descriptor       *desc
 ) {
        u32             rh = roothub_a (ohci);
-       int             ports = rh & RH_A_NDP; 
        u16             temp;
 
        desc->bDescriptorType = 0x29;
        desc->bPwrOn2PwrGood = (rh & RH_A_POTPGT) >> 24;
        desc->bHubContrCurrent = 0;
 
-       desc->bNbrPorts = ports;
-       temp = 1 + (ports / 8);
+       desc->bNbrPorts = ohci->num_ports;
+       temp = 1 + (ohci->num_ports / 8);
        desc->bDescLength = 7 + 2 * temp;
 
        temp = 0;
@@ -421,7 +412,7 @@
        rh = roothub_b (ohci);
        memset(desc->bitmap, 0xff, sizeof(desc->bitmap));
        desc->bitmap [0] = rh & RH_B_DR;
-       if (ports > 7) {
+       if (ohci->num_ports > 7) {
                desc->bitmap [1] = (rh & RH_B_DR) >> 8;
                desc->bitmap [2] = 0xff;
        } else
Index: linux-2.6.12/drivers/usb/host/ohci.h
===================================================================
--- linux-2.6.12.orig/drivers/usb/host/ohci.h   2005-08-25 15:53:19.000000000 
+0100
+++ linux-2.6.12/drivers/usb/host/ohci.h        2005-08-25 15:55:38.000000000 
+0100
@@ -321,7 +321,6 @@
 #define        RH_A_NOCP       (1 << 12)               /* no over current 
protection */
 #define        RH_A_POTPGT     (0xff << 24)            /* power on to power 
good time */
 
-
 /* hcd-private per-urb state */
 typedef struct urb_priv {
        struct ed               *ed;
@@ -383,6 +382,7 @@
        /*
         * driver state
         */
+       int                     num_ports;
        int                     load [NUM_INTS];
        u32                     hc_control;     /* copy of hc control reg */
        unsigned long           next_statechange;       /* suspend/resume */
Index: linux-2.6.12/drivers/usb/host/ohci-pxa27x.c
===================================================================
--- linux-2.6.12.orig/drivers/usb/host/ohci-pxa27x.c    2005-08-25 
15:53:19.000000000 +0100
+++ linux-2.6.12/drivers/usb/host/ohci-pxa27x.c 2005-08-25 15:57:33.000000000 
+0100
@@ -258,6 +258,9 @@
 
        ohci_dbg (ohci, "ohci_pxa27x_start, ohci:%p", ohci);
 
+       /* The value of NDP in roothub_a is incorrect on this hardware */
+       ohci->num_ports = 3;
+
        if ((ret = ohci_init(ohci)) < 0)
                return ret;
 




-------------------------------------------------------
SF.Net email is Sponsored by the Better Software Conference & EXPO
September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices
Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA
Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to