Garrett wrote:
> Juergen Keil wrote:
> > Changing ohci like this enables suspend for ohci on my ASUS P2B-LS box,
> > so that the box does not hang any more on a suspend attempt:
> >
> > diff -r 5e2f30c0e8dc usr/src/uts/common/io/usb/hcd/openhci/ohci.c
> > --- a/usr/src/uts/common/io/usb/hcd/openhci/ohci.c      Tue Nov 06 02:08:12 
> > 2007 -0800
> > +++ b/usr/src/uts/common/io/usb/hcd/openhci/ohci.c      Thu Nov 08 18:14:30 
> > 2007 +0100
> > @@ -7625,6 +7634,12 @@ ohci_intr(caddr_t arg1, caddr_t arg2)
> >             "ohci_intr: Interrupt occurred, arg1 0x%p arg2 0x%p", arg1, 
> > arg2);
> >
> >         mutex_enter(&ohcip->ohci_int_mutex);
> > +
> > +       /* Don't touch a suspended device */
> > +       if (ohcip->ohci_hc_soft_state == OHCI_CTLR_SUSPEND_STATE) {
> > +               mutex_exit(&ohcip->ohci_int_mutex);
> > +               return (DDI_INTR_UNCLAIMED);
> > +       }
> >
> >         /*
> >          * Suppose if we switched to the polled mode from the normal
> >
> >   
> This looks like the right fix for ohci.
> 
> Randy, do you want to take this?


For ehci a similar fix is needed.  I also had to move initialization of 
"ehcip->ehci_hc_soft_state = EHCI_CTLR_OPERATIONAL_STATE" in ehci_init_ctlr()
up a few lines, so that verification of SOF interrupts
works when calling ehci_init_check_status().


My test box still suspends/resumes, and an USB 2.0 hub connected to an ehci
port and an USB 1.x mouse connected to the hub are

diff -r 2fb2a46ebfba usr/src/uts/common/io/usb/hcd/ehci/ehci.c
--- a/usr/src/uts/common/io/usb/hcd/ehci/ehci.c Thu Nov 08 19:30:36 2007 -0800
+++ b/usr/src/uts/common/io/usb/hcd/ehci/ehci.c Fri Nov 09 16:55:29 2007 +0100
@@ -594,6 +594,15 @@ ehci_intr(caddr_t arg1, caddr_t arg2)
        mutex_enter(&ehcip->ehci_int_mutex);
 
        /*
+        * Don't touch a suspended device, in case we get here because of
+        * shared interrupt vector
+        */
+       if (ehcip->ehci_hc_soft_state == EHCI_CTLR_SUSPEND_STATE) {
+               mutex_exit(&ehcip->ehci_int_mutex);
+               return (DDI_INTR_UNCLAIMED);
+       }
+
+       /*
         * Now process the actual ehci interrupt events  that caused
         * invocation of this ehci interrupt handler.
         */
diff -r 2fb2a46ebfba usr/src/uts/common/io/usb/hcd/ehci/ehci_util.c
--- a/usr/src/uts/common/io/usb/hcd/ehci/ehci_util.c    Thu Nov 08 19:30:36 
2007 -0800
+++ b/usr/src/uts/common/io/usb/hcd/ehci/ehci_util.c    Fri Nov 09 17:52:11 
2007 +0100
@@ -1264,6 +1284,9 @@ ehci_init_ctlr(ehci_state_t       *ehcip,
        /* Turn on/off the schedulers */
        ehci_toggle_scheduler(ehcip);
 
+       /* Set host controller soft state to operational */
+       ehcip->ehci_hc_soft_state = EHCI_CTLR_OPERATIONAL_STATE;
+
        /*
         * Set the Periodic Frame List Base Address register with the
         * starting physical address of the Periodic Frame List.
@@ -1293,10 +1316,16 @@ ehci_init_ctlr(ehci_state_t     *ehcip,
 
                if (ehci_init_workaround(ehcip) != DDI_SUCCESS) {
 
+                       /* Set host controller soft state to error */
+                       ehcip->ehci_hc_soft_state = EHCI_CTLR_ERROR_STATE;
+
                        return (DDI_FAILURE);
                }
 
                if (ehci_init_check_status(ehcip) != DDI_SUCCESS) {
+
+                       /* Set host controller soft state to error */
+                       ehcip->ehci_hc_soft_state = EHCI_CTLR_ERROR_STATE;
 
                        return (DDI_FAILURE);
                }
@@ -1307,9 +1336,6 @@ ehci_init_ctlr(ehci_state_t       *ehcip,
 
        /* Route all Root hub ports to EHCI host controller */
        Set_OpReg(ehci_config_flag, EHCI_CONFIG_FLAG_EHCI);
-
-       /* Set host controller soft state to operational */
-       ehcip->ehci_hc_soft_state = EHCI_CTLR_OPERATIONAL_STATE;
 
        return (DDI_SUCCESS);
 }

_______________________________________________
driver-discuss mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/driver-discuss

Reply via email to