diff options
author | sl147100 <none@none> | 2008-04-13 19:12:58 -0700 |
---|---|---|
committer | sl147100 <none@none> | 2008-04-13 19:12:58 -0700 |
commit | 932cf989e70cd9d0418891b72e973f56f41c28b1 (patch) | |
tree | 5abbc1efd1e6025e83312442af67b464c3158c1d | |
parent | 7c64d3750da7fda7e450b8f9b0b963905ded6379 (diff) | |
download | illumos-gate-932cf989e70cd9d0418891b72e973f56f41c28b1.tar.gz |
6681221 Solaris hangs during early boot when EHCI-2 is enabled from BIOS
-rw-r--r-- | usr/src/uts/common/io/usb/hcd/uhci/uhci.c | 35 | ||||
-rw-r--r-- | usr/src/uts/common/io/usb/hcd/uhci/uhciutil.c | 3 | ||||
-rw-r--r-- | usr/src/uts/common/sys/usb/hcd/uhci/uhci.h | 4 |
3 files changed, 32 insertions, 10 deletions
diff --git a/usr/src/uts/common/io/usb/hcd/uhci/uhci.c b/usr/src/uts/common/io/usb/hcd/uhci/uhci.c index da7eb318de..138547052d 100644 --- a/usr/src/uts/common/io/usb/hcd/uhci/uhci.c +++ b/usr/src/uts/common/io/usb/hcd/uhci/uhci.c @@ -921,10 +921,10 @@ uhci_cpr_resume(uhci_state_t *uhcip) static uint_t uhci_intr(caddr_t arg1, caddr_t arg2) { - ushort_t intr_status, cmd_reg; + ushort_t intr_status, cmd_reg, intr_reg; uhci_state_t *uhcip = (uhci_state_t *)arg1; - USB_DPRINTF_L3(PRINT_MASK_INTR, uhcip->uhci_log_hdl, + USB_DPRINTF_L4(PRINT_MASK_INTR, uhcip->uhci_log_hdl, "uhci_intr: Interrupt occurred, arg1 0x%p arg2 0x%p", arg1, arg2); mutex_enter(&uhcip->uhci_int_mutex); @@ -938,17 +938,38 @@ uhci_intr(caddr_t arg1, caddr_t arg2) /* Get the status of the interrupts */ intr_status = Get_OpReg16(USBSTS); + intr_reg = Get_OpReg16(USBINTR); - USB_DPRINTF_L4(PRINT_MASK_INTR, uhcip->uhci_log_hdl, - "uhci_intr: intr_status = %x", intr_status); + USB_DPRINTF_L3(PRINT_MASK_INTR, uhcip->uhci_log_hdl, + "uhci_intr: intr_status = %x, intr_reg = %x", + intr_status, intr_reg); + + /* + * If uhci interrupts are all disabled, the driver should return + * unclaimed. + * HC Process Error and Host System Error interrupts cannot be + * disabled by intr register, and need to be judged separately. + */ + if (((intr_reg & ENABLE_ALL_INTRS) == 0) && + ((intr_status & USBSTS_REG_HC_PROCESS_ERR) == 0) && + ((intr_status & USBSTS_REG_HOST_SYS_ERR) == 0)) { + + USB_DPRINTF_L3(PRINT_MASK_INTR, uhcip->uhci_log_hdl, + "uhci_intr: interrupts disabled, unclaim"); + mutex_exit(&uhcip->uhci_int_mutex); + + return (DDI_INTR_UNCLAIMED); + } /* - * If the intr is not from our controller, just return unclaimed + * If the intr is not from our controller, just return unclaimed. + * HCHalted status bit cannot generate interrupts and should be + * ignored. */ if (!(intr_status & UHCI_INTR_MASK)) { USB_DPRINTF_L3(PRINT_MASK_INTR, uhcip->uhci_log_hdl, - "uhci_intr: unclaimed interrupt"); + "uhci_intr: no interrupt status set, unclaim"); mutex_exit(&uhcip->uhci_int_mutex); return (DDI_INTR_UNCLAIMED); @@ -967,7 +988,7 @@ uhci_intr(caddr_t arg1, caddr_t arg2) if (uhcip->uhci_hc_soft_state != UHCI_CTLR_OPERATIONAL_STATE) { USB_DPRINTF_L2(PRINT_MASK_INTR, uhcip->uhci_log_hdl, - "uhci_intr: uhci controller is not in the operational" + "uhci_intr: uhci controller is not in the operational " "state"); mutex_exit(&uhcip->uhci_int_mutex); diff --git a/usr/src/uts/common/io/usb/hcd/uhci/uhciutil.c b/usr/src/uts/common/io/usb/hcd/uhci/uhciutil.c index 941490b137..72249f0527 100644 --- a/usr/src/uts/common/io/usb/hcd/uhci/uhciutil.c +++ b/usr/src/uts/common/io/usb/hcd/uhci/uhciutil.c @@ -462,6 +462,8 @@ uhci_init_ctlr(uhci_state_t *uhcip) uint_t cmd_reg; uint_t frame_base_addr; + mutex_enter(&uhcip->uhci_int_mutex); + USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, "uhci_init_ctlr:"); /* @@ -479,7 +481,6 @@ uhci_init_ctlr(uhci_state_t *uhcip) */ Set_OpReg16(USBINTR, DISABLE_ALL_INTRS); - mutex_enter(&uhcip->uhci_int_mutex); cmd_reg = Get_OpReg16(USBCMD); cmd_reg &= (~USBCMD_REG_HC_RUN); diff --git a/usr/src/uts/common/sys/usb/hcd/uhci/uhci.h b/usr/src/uts/common/sys/usb/hcd/uhci/uhci.h index 90bcb1a476..394106cd61 100644 --- a/usr/src/uts/common/sys/usb/hcd/uhci/uhci.h +++ b/usr/src/uts/common/sys/usb/hcd/uhci/uhci.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -108,7 +108,7 @@ typedef volatile struct hcr_regs { #define ENABLE_ALL_INTRS 0x000F #define DISABLE_ALL_INTRS 0x0000 -#define UHCI_INTR_MASK 0x3f +#define UHCI_INTR_MASK 0x1f #define SetReg32(hndl, addr, val) ddi_put32((hndl), \ |