summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsl147100 <none@none>2008-04-13 19:12:58 -0700
committersl147100 <none@none>2008-04-13 19:12:58 -0700
commit932cf989e70cd9d0418891b72e973f56f41c28b1 (patch)
tree5abbc1efd1e6025e83312442af67b464c3158c1d
parent7c64d3750da7fda7e450b8f9b0b963905ded6379 (diff)
downloadillumos-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.c35
-rw-r--r--usr/src/uts/common/io/usb/hcd/uhci/uhciutil.c3
-rw-r--r--usr/src/uts/common/sys/usb/hcd/uhci/uhci.h4
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), \