--- old/usr/src/uts/common/io/usb/hcd/ehci/ehci_util.c	Mon Aug  5 17:32:14 2019
+++ new/usr/src/uts/common/io/usb/hcd/ehci/ehci_util.c	Mon Aug  5 17:32:14 2019
@@ -21,9 +21,14 @@
 
 /*
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, Joyent, Inc.
  */
 
 /*
+ * Copyright 2018 Nexenta Systems, Inc.
+ */
+
+/*
  * EHCI Host Controller Driver (EHCI)
  *
  * The EHCI driver is a software driver which interfaces to the Universal
@@ -745,7 +750,7 @@
 		(void) thread_create(NULL, 0, ehci_poll_intr, ehcip, 0, &p0,
 		    TS_RUN, maxclsyspri);
 
-		goto skip_intr;
+		return (DDI_SUCCESS);
 	}
 
 #if defined(__x86)
@@ -819,11 +824,6 @@
 		ehcip->ehci_flags |= EHCI_INTR;
 	}
 
-skip_intr:
-	/* Create prototype for advance on async schedule */
-	cv_init(&ehcip->ehci_async_schedule_advance_cv,
-	    NULL, CV_DRIVER, NULL);
-
 	return (DDI_SUCCESS);
 }
 
@@ -834,8 +834,7 @@
  * Register FIXED or MSI interrupts.
  */
 static int
-ehci_add_intrs(ehci_state_t	*ehcip,
-		int		intr_type)
+ehci_add_intrs(ehci_state_t *ehcip, int intr_type)
 {
 	int	actual, avail, intr_size, count = 0;
 	int	i, flag, ret;
@@ -1174,66 +1173,13 @@
 	return (DDI_SUCCESS);
 }
 
-
 /*
- * ehci_init_check_status
- *
- * Check if EHCI host controller is running
- */
-int
-ehci_init_check_status(ehci_state_t	*ehcip)
-{
-	clock_t			sof_time_wait;
-
-	/*
-	 * Get the number of clock ticks to wait.
-	 * This is based on the maximum time it takes for a frame list rollover
-	 * and maximum time wait for SOFs to begin.
-	 */
-	sof_time_wait = drv_usectohz((EHCI_NUM_PERIODIC_FRAME_LISTS * 1000) +
-	    EHCI_SOF_TIMEWAIT);
-
-	/* Tell the ISR to broadcast ehci_async_schedule_advance_cv */
-	ehcip->ehci_flags |= EHCI_CV_INTR;
-
-	/* We need to add a delay to allow the chip time to start running */
-	(void) cv_reltimedwait(&ehcip->ehci_async_schedule_advance_cv,
-	    &ehcip->ehci_int_mutex, sof_time_wait, TR_CLOCK_TICK);
-
-	/*
-	 * Check EHCI host controller is running, otherwise return failure.
-	 */
-	if ((ehcip->ehci_flags & EHCI_CV_INTR) ||
-	    (Get_OpReg(ehci_status) & EHCI_STS_HOST_CTRL_HALTED)) {
-
-		USB_DPRINTF_L0(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
-		    "No SOF interrupts have been received, this USB EHCI host"
-		    "controller is unusable");
-
-		/*
-		 * Route all Root hub ports to Classic host
-		 * controller, in case this is an unusable ALI M5273
-		 * EHCI controller.
-		 */
-		if (ehcip->ehci_vendor_id == PCI_VENDOR_ALI) {
-			Set_OpReg(ehci_config_flag, EHCI_CONFIG_FLAG_CLASSIC);
-		}
-
-		return (DDI_FAILURE);
-	}
-
-	return (DDI_SUCCESS);
-}
-
-
-/*
  * ehci_init_ctlr:
  *
  * Initialize the Host Controller (HC).
  */
 int
-ehci_init_ctlr(ehci_state_t	*ehcip,
-		int		init_type)
+ehci_init_ctlr(ehci_state_t *ehcip, int init_type)
 {
 	USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl, "ehci_init_ctlr:");
 
@@ -1324,7 +1270,6 @@
 	ASSERT(Get_OpReg(ehci_command) & EHCI_CMD_HOST_CTRL_RUN);
 
 	if (init_type == EHCI_NORMAL_INITIALIZATION) {
-
 		if (ehci_init_workaround(ehcip) != DDI_SUCCESS) {
 
 			/* Set host controller soft state to error */
@@ -1332,17 +1277,6 @@
 
 			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);
-		}
-
-		USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
-		    "ehci_init_ctlr: SOF's have started");
 	}
 
 	/* Route all Root hub ports to EHCI host controller */
@@ -1406,6 +1340,19 @@
 		extended_cap = pci_config_get32(ehcip->ehci_config_handle,
 		    extended_cap_offset);
 
+		/*
+		 * It's possible that we'll receive an invalid PCI read here due
+		 * to something going wrong due to platform firmware. This has
+		 * been observed in the wild depending on the version of ACPI in
+		 * use. If this happens, we'll assume that the capability does
+		 * not exist and that we do not need to take control from the
+		 * BIOS.
+		 */
+		if (extended_cap == PCI_EINVAL32) {
+			extended_cap_id = EHCI_EX_CAP_ID_RESERVED;
+			break;
+		}
+
 		/* Get the capability ID */
 		extended_cap_id = (extended_cap & EHCI_EX_CAP_ID) >>
 		    EHCI_EX_CAP_ID_SHIFT;
@@ -1418,6 +1365,7 @@
 		/* Get the offset of the next capability */
 		extended_cap_offset = (extended_cap & EHCI_EX_CAP_NEXT_PTR) >>
 		    EHCI_EX_CAP_NEXT_PTR_SHIFT;
+
 	}
 
 	/*
@@ -1931,9 +1879,6 @@
 	if (flags & EHCI_INTR) {
 		/* Destroy the mutex */
 		mutex_destroy(&ehcip->ehci_int_mutex);
-
-		/* Destroy the async schedule advance condition variable */
-		cv_destroy(&ehcip->ehci_async_schedule_advance_cv);
 	}
 
 	/* clean up kstat structs */
@@ -2976,7 +2921,8 @@
  * Based on the "real" array leaf node and interval, get the periodic node.
  */
 static uint_t
-ehci_find_periodic_node(uint_t leaf, int interval) {
+ehci_find_periodic_node(uint_t leaf, int interval)
+{
 	uint_t	lattice_leaf;
 	uint_t	height = ehci_lattice_height(interval);
 	uint_t	pnode;
