Hmm, does ddi_intr_disable() require a PCI2.3 device - a device that implements bit 10 (pci interrupt disable) in the pci device control register?
I'm affraid the ICH4-M chipset does not implment that bit, for the uhci controller... (according to Intel's specs...) ICH5, ICH6, ... has it. > So a possible workaround might be to use the DDI to disable interrupt > receipt (ddi_intr_disable().) This might require conversion of the uhci > driver to the new style interrupt APIs. I've not looked at it that closely. > > -- Garrett > > Juergen Keil wrote: > >> Looking at the code for uhci, its clearly busted. > >> > >> The code needs to set a suspended flag (under a lock), and check that it > >> is not set when servicing interrupts. > >> > > > > Such a flag already exists: uhcip->uhci_hc_soft_state / UHCI_CTLR_SUSPEND_STATE, > > and it is set and tested protected by the uhci_int_mutex lock. > > > > Problem is that uhci_cpr_suspend() temporarily releases the uhci_int_mutex > > lock while calling delay(), and apparently it releases the lock before > > the uhci hw is really stopped. And before the uhcip->uhci_hc_soft_state > > flag is set to UHCI_CTLR_SUSPEND_STATE. That delay() call is exactly where > > my Toshiba Laptop is hanging, when I try to S3-suspend it. > > > > > > > > > >> But, I see another problem, which is that perhaps the code is not > >> clearing the interrupts when it disables them in uhci_cpr_suspend(). > >> Still, it seems like the device should not be generating interrupts to > >> the hardware if the interrupt enable status bit is cleared. *That* > >> sounds like a potential hardware bug. > >> > > > > Yes, looks like > > > > - either a new new uhci interrupt is generated between lines 831 .. 834 > > (which seems unlikely, because so far, the S3-suspend hang happens > > every time) > > > > - or the Set_OpReg16(USBINTR, DISABLE_ALL_INTRS); doesn't have an > > effect immediately - so that we can receive at least one more uhci > > interrupt while we're inside the delay call at line 839. > > > > 816 /* > > 817 * uhci_cpr_suspend > > 818 */ > > 819 static int > > 820 uhci_cpr_suspend(uhci_state_t *uhcip) > > 821 { > > 822 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, > > 823 "uhci_cpr_suspend:"); > > 824 > > 825 /* Call into the root hub and suspend it */ > > 826 if (usba_hubdi_detach(uhcip->uhci_dip, DDI_SUSPEND) != DDI_SUCCESS) { > > 827 > > 828 return (DDI_FAILURE); > > 829 } > > 830 > > 831 mutex_enter(&uhcip->uhci_int_mutex); > > 832 > > 833 /* Disable interrupts */ > > 834 Set_OpReg16(USBINTR, DISABLE_ALL_INTRS); > > 835 > > 836 mutex_exit(&uhcip->uhci_int_mutex); > > 837 > > 838 /* Wait for SOF time to handle the scheduled interrupt */ > > 839 delay(drv_usectohz(UHCI_TIMEWAIT)); > > > > > > Btw. the uhci controller im my Toshiba Tecra S1 laptop is part of an > > Intel ICH4-M chipset. > > > > > > > > > >> -- Garrett > >> > >> J??rgen Keil wrote: > >> > >>> Can anyone reproduce a hanging system when trying to use S3 suspend-to-ram, > >>> immediately after the first uhci driver instance gets suspended? > >>> Most likely this is an issue only on systems where uhci is sharing > >>> it's interrupt vector with other devices. > >>> > >>> My Toshiba Tecra S1 laptop used to be able to enter S3 suspend-to-ram > >>> mode. > >>> > >>> Seems that since the putback for 6681221 "Solaris hangs during early boot > >>> when EHCI-2 is enabled from BIOS" S3-suspend is broken. As soon as the first > >>> uhci controller gets suspended (uhci0), system hangs (with an interrupt storm?). > >>> The laptop doesn't reach S3-STR state any more. > >>> > >>> There is an interrupt pending for uhci0 (intr_status == 1), but interrupts > >>> are supposed to be disabled (intr_reg == 0), so the code returns from > >>> uhci_intr without acknowledging the pending interrupt (lines 954 - 952 in uhci.c) . > >>> Interrupt handler is immediately re-entered; there's no more progress with > >>> S3-suspend. > >>> > >>> usr/src/uts/common/io/usb/hcd/uhci/uhci.c: > >>> 940 /* Get the status of the interrupts */ > >>> 941 intr_status = Get_OpReg16(USBSTS); > >>> 942 intr_reg = Get_OpReg16(USBINTR); > >>> 943 > >>> 944 USB_DPRINTF_L3(PRINT_MASK_INTR, uhcip->uhci_log_hdl, > >>> 945 "uhci_intr: intr_status = %x, intr_reg = %x", > >>> 946 intr_status, intr_reg); > >>> 947 > >>> 948 /* > >>> 949 * If uhci interrupts are all disabled, the driver should return > >>> 950 * unclaimed. > >>> 951 * HC Process Error and Host System Error interrupts cannot be > >>> 952 * disabled by intr register, and need to be judged separately. > >>> 953 */ > >>> 954 if (((intr_reg & ENABLE_ALL_INTRS) == 0) && > >>> 955 ((intr_status & USBSTS_REG_HC_PROCESS_ERR) == 0) && > >>> 956 ((intr_status & USBSTS_REG_HOST_SYS_ERR) == 0)) { > >>> 957 > >>> 958 USB_DPRINTF_L3(PRINT_MASK_INTR, uhcip->uhci_log_hdl, > >>> 959 "uhci_intr: interrupts disabled, unclaim"); > >>> 960 mutex_exit(&uhcip->uhci_int_mutex); > >>> 961 > >>> 962 return (DDI_INTR_UNCLAIMED); > >>> 963 } > >>> > >>> > >>> This message posted from opensolaris.org > >>> _______________________________________________ > >>> laptop-discuss mailing list > >>> laptop-discuss at opensolaris.org