--- old/usr/src/uts/common/io/usb/hcd/xhci/xhci.c	Mon Jul  9 10:24:41 2018
+++ new/usr/src/uts/common/io/usb/hcd/xhci/xhci.c	Mon Jul  9 10:24:41 2018
@@ -11,6 +11,7 @@
 
 /*
  * Copyright (c) 2017, Joyent, Inc.
+ * Copyright (c) 2018, Western Digital Corporation.
  */
 
 /*
@@ -86,39 +87,39 @@
  *
  * There are four different kinds of endpoints:
  *
- * 	BULK		These transfers are large transfers of data to or from
- * 			a device. The most common use for bulk transfers is for
- * 			mass storage devices. Though they are often also used by
- * 			network devices and more. Bulk endpoints do not have an
- * 			explicit time component to them. They are always used
- * 			for one-shot transfers.
+ *	BULK		These transfers are large transfers of data to or from
+ *			a device. The most common use for bulk transfers is for
+ *			mass storage devices. Though they are often also used by
+ *			network devices and more. Bulk endpoints do not have an
+ *			explicit time component to them. They are always used
+ *			for one-shot transfers.
  *
- * 	CONTROL		These transfers are used to manipulate devices
- * 			themselves and are used for USB protocol level
- * 			operations (whether device-specific, class-specific, or
- * 			generic across all of USB). Unlike other transfers,
- * 			control transfers are always bi-directional and use
- * 			different kinds of transfers.
+ *	CONTROL		These transfers are used to manipulate devices
+ *			themselves and are used for USB protocol level
+ *			operations (whether device-specific, class-specific, or
+ *			generic across all of USB). Unlike other transfers,
+ *			control transfers are always bi-directional and use
+ *			different kinds of transfers.
  *
- * 	INTERRUPT	Interrupt transfers are used for small transfers that
- * 			happen infrequently, but need reasonable latency. A good
- * 			example of interrupt transfers is to receive input from
- * 			a USB keyboard. Interrupt-IN transfers are generally
- * 			polled. Meaning that a client (device driver) opens up
- * 			an interrupt-IN pipe to poll on it, and receives
- * 			periodic updates whenever there is information
- * 			available. However, Interrupt transfers can be used
- * 			as one-shot transfers both going IN and OUT.
+ *	INTERRUPT	Interrupt transfers are used for small transfers that
+ *			happen infrequently, but need reasonable latency. A good
+ *			example of interrupt transfers is to receive input from
+ *			a USB keyboard. Interrupt-IN transfers are generally
+ *			polled. Meaning that a client (device driver) opens up
+ *			an interrupt-IN pipe to poll on it, and receives
+ *			periodic updates whenever there is information
+ *			available. However, Interrupt transfers can be used
+ *			as one-shot transfers both going IN and OUT.
  *
- * 	ISOCHRONOUS	These transfers are things that happen once per
- * 			time-interval at a very regular rate. A good example of
- * 			these transfers are for audio and video. A device may
- * 			describe an interval as 10ms at which point it will read
- * 			or write the next batch of data every 10ms and transform
- * 			it for the user. There are no one-shot Isochronous-IN
- * 			transfers. There are one-shot Isochronous-OUT transfers,
- * 			but these are used by device drivers to always provide
- * 			the system with sufficient data.
+ *	ISOCHRONOUS	These transfers are things that happen once per
+ *			time-interval at a very regular rate. A good example of
+ *			these transfers are for audio and video. A device may
+ *			describe an interval as 10ms at which point it will read
+ *			or write the next batch of data every 10ms and transform
+ *			it for the user. There are no one-shot Isochronous-IN
+ *			transfers. There are one-shot Isochronous-OUT transfers,
+ *			but these are used by device drivers to always provide
+ *			the system with sufficient data.
  *
  * To find out information about the endpoints, USB devices have a series of
  * descriptors that cover different aspects of the device. For example, there
@@ -220,67 +221,67 @@
  * purpose of each of these files.
  *
  * xhci_command.c:	This file contains the logic to issue commands to the
- * 			controller as well as the actual functions that the
- * 			other parts of the driver use to cause those commands.
+ *			controller as well as the actual functions that the
+ *			other parts of the driver use to cause those commands.
  *
  * xhci_context.c:	This file manages various data structures used by the
- * 			controller to manage the controller's and device's
- * 			context data structures. See more in the xHCI Overview
- * 			and General Design for more information.
+ *			controller to manage the controller's and device's
+ *			context data structures. See more in the xHCI Overview
+ *			and General Design for more information.
  *
  * xhci_dma.c:		This manages the allocation of DMA memory and DMA
- * 			attributes for controller, whether memory is for a
- * 			transfer or something else. This file also deals with
- * 			all the logic of getting data in and out of DMA buffers.
+ *			attributes for controller, whether memory is for a
+ *			transfer or something else. This file also deals with
+ *			all the logic of getting data in and out of DMA buffers.
  *
  * xhci_endpoint.c:	This manages all of the logic of handling endpoints or
- * 			pipes. It deals with endpoint configuration, I/O
- * 			scheduling, timeouts, and callbacks to USBA.
+ *			pipes. It deals with endpoint configuration, I/O
+ *			scheduling, timeouts, and callbacks to USBA.
  *
  * xhci_event.c:	This manages callbacks from the hardware to the driver.
- * 			This covers command completion notifications and I/O
- * 			notifications.
+ *			This covers command completion notifications and I/O
+ *			notifications.
  *
  * xhci_hub.c:		This manages the virtual root-hub. It basically
- * 			implements and translates all of the USB level requests
- * 			into xhci specific implements. It also contains the
- * 			functions to register this hub with USBA.
+ *			implements and translates all of the USB level requests
+ *			into xhci specific implements. It also contains the
+ *			functions to register this hub with USBA.
  *
  * xhci_intr.c:		This manages the underlying interrupt allocation,
- * 			interrupt moderation, and interrupt routines.
+ *			interrupt moderation, and interrupt routines.
  *
  * xhci_quirks.c:	This manages information about buggy hardware that's
- * 			been collected and experienced primarily from other
- * 			systems.
+ *			been collected and experienced primarily from other
+ *			systems.
  *
  * xhci_ring.c:		This manages the abstraction of a ring in xhci, which is
- * 			the primary of communication between the driver and the
- * 			hardware, whether for the controller or a device.
+ *			the primary of communication between the driver and the
+ *			hardware, whether for the controller or a device.
  *
  * xhci_usba.c:		This implements all of the HCDI functions required by
- * 			USBA. This is the main entry point that drivers and the
- * 			kernel frameworks will reach to start any operation.
- * 			Many functions here will end up in the command and
- * 			endpoint code.
+ *			USBA. This is the main entry point that drivers and the
+ *			kernel frameworks will reach to start any operation.
+ *			Many functions here will end up in the command and
+ *			endpoint code.
  *
  * xhci.c:		This provides the main kernel DDI interfaces and
- * 			performs device initialization.
+ *			performs device initialization.
  *
  * xhci.h:		This is the primary header file which defines
- * 			illumos-specific data structures and constants to manage
- * 			the system.
+ *			illumos-specific data structures and constants to manage
+ *			the system.
  *
  * xhcireg.h:		This header file defines all of the register offsets,
- * 			masks, and related macros. It also contains all of the
- * 			constants that are used in various structures as defined
- * 			by the specification, such as command offsets, etc.
+ *			masks, and related macros. It also contains all of the
+ *			constants that are used in various structures as defined
+ *			by the specification, such as command offsets, etc.
  *
  * xhci_ioctl.h:	This contains a few private ioctls that are used by a
- * 			private debugging command. These are private.
+ *			private debugging command. These are private.
  *
  * cmd/xhci/xhci_portsc:	This is a private utility that can be useful for
- * 				debugging xhci state. It is the only consumer of
- * 				xhci_ioctl.h and the private ioctls.
+ *				debugging xhci state. It is the only consumer of
+ *				xhci_ioctl.h and the private ioctls.
  *
  * ----------------------------------
  * xHCI Overview and Structure Layout
@@ -328,25 +329,25 @@
  * contexts look like:
  *
  *
- *      DCBAA
- *    +--------+                    Device Context
+ *	DCBAA
+ *    +--------+		    Device Context
  *    | Slot 0 |------------------>+--------------+
- *    +--------+                   | Slot Context |
- *    |  ...   |                   +--------------+       +----------+
- *    +--------+   +------+        |  Endpoint 0  |------>| I/O Ring |
- *    | Slot n |-->| NULL |        | Context (Bi) |       +----------+
- *    +--------+   +------+        +--------------+
- *                                 |  Endpoint 1  |
- *                                 | Context (Out)|
- *                                 +--------------+
- *                                 |  Endpoint 1  |
- *                                 | Context (In) |
- *                                 +--------------+
- *                                 |      ...     |
- *                                 +--------------+
- *                                 | Endpoint 15  |
- *                                 | Context (In) |
- *                                 +--------------+
+ *    +--------+		   | Slot Context |
+ *    |  ...   |		   +--------------+	  +----------+
+ *    +--------+   +------+	   |  Endpoint 0  |------>| I/O Ring |
+ *    | Slot n |-->| NULL |	   | Context (Bi) |	  +----------+
+ *    +--------+   +------+	   +--------------+
+ *				   |  Endpoint 1  |
+ *				   | Context (Out)|
+ *				   +--------------+
+ *				   |  Endpoint 1  |
+ *				   | Context (In) |
+ *				   +--------------+
+ *				   |	  ...	  |
+ *				   +--------------+
+ *				   | Endpoint 15  |
+ *				   | Context (In) |
+ *				   +--------------+
  *
  * These contexts are always owned by the controller, though we can read them
  * after various operations complete. Commands that toggle device state use a
@@ -403,30 +404,30 @@
  * We also have a notion of timed out and quiescing. The following image
  * summarizes the states and transitions:
  *
- *     +------+                                +-----------+
+ *     +------+				       +-----------+
  *     | Idle |---------*--------------------->|  Running  |<-+
- *     +------+         . I/O queued on        +-----------+  |
- *        ^               ring and timeout        |  |  |     |
- *        |               scheduled.              |  |  |     |
- *        |                                       |  |  |     |
- *        +-----*---------------------------------+  |  |     |
- *        |     . No I/Os remain                     |  |     |
- *        |                                          |  |     |
- *        |                +------*------------------+  |     |
- *        |                |      . Timeout             |     |
- *        |                |        fires for           |     |
- *        |                |        I/O                 |     |
- *        |                v                            v     |
- *        |          +-----------+                +--------+  |
- *        |          | Timed Out |                | Halted |  |
- *        |          +-----------+                +--------+  |
- *        |             |                           |         |
- *        |             |   +-----------+           |         |
- *        |             +-->| Quiescing |<----------+         |
- *        |                 +-----------+                     |
- *        |   No TRBs.           |                . TRBs      |
- *        |   remain .           |                . Remain    |
- *        +----------*----<------+-------->-------*-----------+
+ *     +------+		. I/O queued on        +-----------+  |
+ *	  ^		  ring and timeout	  |  |	|     |
+ *	  |		  scheduled.		  |  |	|     |
+ *	  |					  |  |	|     |
+ *	  +-----*---------------------------------+  |	|     |
+ *	  |	. No I/Os remain		     |	|     |
+ *	  |					     |	|     |
+ *	  |		   +------*------------------+	|     |
+ *	  |		   |	  . Timeout		|     |
+ *	  |		   |	    fires for		|     |
+ *	  |		   |	    I/O			|     |
+ *	  |		   v				v     |
+ *	  |	     +-----------+		  +--------+  |
+ *	  |	     | Timed Out |		  | Halted |  |
+ *	  |	     +-----------+		  +--------+  |
+ *	  |		|			    |	      |
+ *	  |		|   +-----------+	    |	      |
+ *	  |		+-->| Quiescing |<----------+	      |
+ *	  |		    +-----------+		      |
+ *	  |   No TRBs.		 |		  . TRBs      |
+ *	  |   remain .		 |		  . Remain    |
+ *	  +----------*----<------+-------->-------*-----------+
  *
  * Normally, a given endpoint will oscillate between having TRBs scheduled and
  * not. Every time a new I/O is added to the endpoint, we'll ring the doorbell,
@@ -463,26 +464,26 @@
  * The following image describes the state machine for the timeout logic. It
  * ties into the image above.
  *
- *         +----------+                            +---------+
- *         | Disabled |-----*--------------------->| Enabled |<--+
- *         +----------+     . TRBs scheduled       +---------+   *. 1 sec timer
- *             ^              and no active          |  |  |     |  fires and
- *             |              timer.                 |  |  |     |  another
- *             |                                     |  |  +--+--+  quiesce, in
- *             |                                     |  |     |     a bad state,
- *             +------*------------------------------+  |     ^     or decrement
- *             |      . 1 sec timer                     |     |     I/O timeout
- *             |        fires and                       |     |
- *             |        no TRBs or                      |     +--------------+
- *             |        endpoint shutdown               |                    |
- *             |                                        *. . timer counter   |
- *             ^                                        |    reaches zero    |
- *             |                                        v                    |
- *             |                                +--------------+             |
- *             +-------------*---------------<--| Quiesce ring |->---*-------+
- *                           . No more          | and fail I/O |     . restart
- *                             I/Os             +--------------+       timer as
- *                                                                     more I/Os
+ *	   +----------+				   +---------+
+ *	   | Disabled |-----*--------------------->| Enabled |<--+
+ *	   +----------+     . TRBs scheduled	   +---------+	 *. 1 sec timer
+ *	       ^	      and no active	     |	|  |	 |  fires and
+ *	       |	      timer.		     |	|  |	 |  another
+ *	       |				     |	|  +--+--+  quiesce, in
+ *	       |				     |	|     |     a bad state,
+ *	       +------*------------------------------+	|     ^     or decrement
+ *	       |      . 1 sec timer			|     |     I/O timeout
+ *	       |	fires and			|     |
+ *	       |	no TRBs or			|     +--------------+
+ *	       |	endpoint shutdown		|		     |
+ *	       |					*. . timer counter   |
+ *	       ^					|    reaches zero    |
+ *	       |					v		     |
+ *	       |				+--------------+	     |
+ *	       +-------------*---------------<--| Quiesce ring |->---*-------+
+ *			     . No more		| and fail I/O |     . restart
+ *			       I/Os		+--------------+       timer as
+ *								       more I/Os
  *
  * As we described above, when there are active TRBs and I/Os, a 1 second
  * timeout(9F) will be active. Each second, we decrement a counter on the
@@ -530,114 +531,114 @@
  * system.
  *
  *     +------------------------+
- *     | Per-Controller         |
- *     | Structure              |
- *     | xhci_t                 |
- *     |                        |
- *     | uint_t              ---+--> Capability regs offset
- *     | uint_t              ---+--> Operational regs offset
- *     | uint_t              ---+--> Runtime regs offset
- *     | uint_t              ---+--> Doorbell regs offset
+ *     | Per-Controller		|
+ *     | Structure		|
+ *     | xhci_t			|
+ *     |			|
+ *     | uint_t		     ---+--> Capability regs offset
+ *     | uint_t		     ---+--> Operational regs offset
+ *     | uint_t		     ---+--> Runtime regs offset
+ *     | uint_t		     ---+--> Doorbell regs offset
  *     | xhci_state_flags_t  ---+--> Device state flags
- *     | xhci_quirks_t       ---+--> Device quirk flags
+ *     | xhci_quirks_t	     ---+--> Device quirk flags
  *     | xhci_capability_t   ---+--> Controller capability structure
- *     | xhci_dcbaa_t        ---+----------------------------------+
- *     | xhci_scratchpad_t   ---+---------+                        |
- *     | xhci_command_ing_t  ---+------+  |                        v
- *     | xhci_event_ring_t   ---+----+ |  |              +---------------------+
- *     | xhci_usba_t         ---+--+ | |  |              | Device Context      |
- *     +------------------------+  | | |  |              | Base Address        |
- *                                 | | |  |              | Array Structure     |
- *                                 | | |  |              | xhci_dcbaa_t        |
- * +-------------------------------+ | |  |              |                     |
- * | +-------------------------------+ |  |  DCBAA KVA <-+--        uint64_t * |
- * | |    +----------------------------+  | DMA Buffer <-+-- xhci_dma_buffer_t |
- * | |    v                               |              +---------------------+
- * | | +--------------------------+       +-----------------------+
- * | | | Event Ring               |                               |
- * | | | Management               |                               |
- * | | | xhci_event_ring_t        |                               v
- * | | |                          |   Event Ring        +----------------------+
- * | | | xhci_event_segment_t * --|-> Segment VA        |   Scratchpad (Extra  |
- * | | | xhci_dma_buffer_t      --|-> Segment DMA Buf.  |   Controller Memory) |
- * | | | xhci_ring_t            --|--+                  |    xhci_scratchpad_t |
- * | | +--------------------------+  |      Scratchpad  |                      |
- * | |                               | Base Array KVA <-+-          uint64_t * |
- * | +------------+                  | Array DMA Buf. <-+-   xhci_dma_buffer_t |
- * |              v                  | Scratchpad DMA <-+- xhci_dma_buffer_t * |
- * |   +---------------------------+ | Buffer per page  +----------------------+
- * |   | Command Ring              | |
- * |   | xhci_command_ring_t       | +------------------------------+
- * |   |                           |                                |
- * |   | xhci_ring_t             --+-> Command Ring --->------------+
- * |   | list_t                  --+-> Command List                 v
- * |   | timeout_id_t            --+-> Timeout State     +---------------------+
- * |   | xhci_command_ring_state_t +-> State Flags       | I/O Ring            |
- * |   +---------------------------+                     | xhci_ring_t         |
- * |                                                     |                     |
- * |                                     Ring DMA Buf. <-+-- xhci_dma_buffer_t |
- * |                                       Ring Length <-+--            uint_t |
- * |                                    Ring Entry KVA <-+--      xhci_trb_t * |
- * |    +---------------------------+        Ring Head <-+--            uint_t |
- * +--->| USBA State                |        Ring Tail <-+--            uint_t |
- *      | xhci_usba_t               |       Ring Cycle <-+--            uint_t |
- *      |                           |                    +---------------------+
- *      | usba_hcdi_ops_t *        -+-> USBA Ops Vector                       ^
- *      | usb_dev_dscr_t           -+-> USB Virtual Device Descriptor         |
- *      | usb_ss_hub_descr_t       -+-> USB Virtual Hub Descriptor            |
- *      | usba_pipe_handle_data_t * +-> Interrupt polling client              |
- *      | usb_intr_req_t           -+-> Interrupt polling request             |
- *      | uint32_t                --+-> Interrupt polling device mask         |
- *      | list_t                  --+-> Pipe List (Active Users)              |
- *      | list_t                  --+-------------------+                     |
- *      +---------------------------+                   |                     ^
- *                                                      |                     |
- *                                                      v                     |
- *     +-------------------------------+             +---------------+        |
- *     | USB Device                    |------------>| USB Device    |--> ... |
- *     | xhci_device_t                 |             | xhci_device_t |        |
- *     |                               |             +---------------+        |
- *     | usb_port_t                  --+-> USB Port plugged into              |
- *     | uint8_t                     --+-> Slot Number                        |
- *     | boolean_t                   --+-> Address Assigned                   |
- *     | usba_device_t *             --+-> USBA Device State                  |
- *     | xhci_dma_buffer_t           --+-> Input Context DMA Buffer           |
- *     | xhci_input_context_t *      --+-> Input Context KVA                  |
- *     | xhci_slot_contex_t *        --+-> Input Slot Context KVA             |
- *     | xhci_endpoint_context_t *[] --+-> Input Endpoint Context KVA         |
- *     | xhci_dma_buffer_t           --+-> Output Context DMA Buffer          |
- *     | xhci_slot_context_t *       --+-> Output Slot Context KVA            ^
- *     | xhci_endpoint_context_t *[] --+-> Output Endpoint Context KVA        |
- *     | xhci_endpoint_t *[]         --+-> Endpoint Tracking ---+             |
- *     +-------------------------------+                        |             |
- *                                                              |             |
- *                                                              v             |
- *     +------------------------------+            +-----------------+        |
- *     | Endpoint Data                |----------->| Endpoint Data   |--> ... |
- *     | xhci_endpoint_t              |            | xhci_endpoint_t |        |
- *     |                              |            +-----------------+        |
- *     | int                        --+-> Endpoint Number                     |
- *     | int                        --+-> Endpoint Type                       |
- *     | xhci_endpoint_state_t      --+-> Endpoint State                      |
- *     | timeout_id_t               --+-> Endpoint Timeout State              |
- *     | usba_pipe_handle_data_t *  --+-> USBA Client Handle                  |
- *     | xhci_ring_t                --+-> Endpoint I/O Ring  -------->--------+
- *     | list_t                     --+-> Transfer List --------+
- *     +------------------------------+                         |
- *                                                              v
- *     +-------------------------+                  +--------------------+
- *     | Transfer Structure      |----------------->| Transfer Structure |-> ...
- *     | xhci_transfer_t         |                  | xhci_transfer_t    |
- *     |                         |                  +--------------------+
+ *     | xhci_dcbaa_t	     ---+----------------------------------+
+ *     | xhci_scratchpad_t   ---+---------+			   |
+ *     | xhci_command_ing_t  ---+------+  |			   v
+ *     | xhci_event_ring_t   ---+----+ |  |		 +---------------------+
+ *     | xhci_usba_t	     ---+--+ | |  |		 | Device Context      |
+ *     +------------------------+  | | |  |		 | Base Address        |
+ *				   | | |  |		 | Array Structure     |
+ *				   | | |  |		 | xhci_dcbaa_t        |
+ * +-------------------------------+ | |  |		 |		       |
+ * | +-------------------------------+ |  |  DCBAA KVA <-+--	    uint64_t * |
+ * | |	  +----------------------------+  | DMA Buffer <-+-- xhci_dma_buffer_t |
+ * | |	  v				  |		 +---------------------+
+ * | | +--------------------------+	  +-----------------------+
+ * | | | Event Ring		  |				  |
+ * | | | Management		  |				  |
+ * | | | xhci_event_ring_t	  |				  v
+ * | | |			  |   Event Ring	+----------------------+
+ * | | | xhci_event_segment_t * --|-> Segment VA	|   Scratchpad (Extra  |
+ * | | | xhci_dma_buffer_t	--|-> Segment DMA Buf.	|   Controller Memory) |
+ * | | | xhci_ring_t		--|--+			|    xhci_scratchpad_t |
+ * | | +--------------------------+  |	    Scratchpad	|		       |
+ * | |				     | Base Array KVA <-+-	    uint64_t * |
+ * | +------------+		     | Array DMA Buf. <-+-   xhci_dma_buffer_t |
+ * |		  v		     | Scratchpad DMA <-+- xhci_dma_buffer_t * |
+ * |   +---------------------------+ | Buffer per page	+----------------------+
+ * |   | Command Ring		   | |
+ * |   | xhci_command_ring_t	   | +------------------------------+
+ * |   |			   |				    |
+ * |   | xhci_ring_t		 --+-> Command Ring --->------------+
+ * |   | list_t			 --+-> Command List		    v
+ * |   | timeout_id_t		 --+-> Timeout State	 +---------------------+
+ * |   | xhci_command_ring_state_t +-> State Flags	 | I/O Ring	       |
+ * |   +---------------------------+			 | xhci_ring_t	       |
+ * |							 |		       |
+ * |					 Ring DMA Buf. <-+-- xhci_dma_buffer_t |
+ * |					   Ring Length <-+--		uint_t |
+ * |					Ring Entry KVA <-+--	  xhci_trb_t * |
+ * |	+---------------------------+	     Ring Head <-+--		uint_t |
+ * +--->| USBA State		    |	     Ring Tail <-+--		uint_t |
+ *	| xhci_usba_t		    |	    Ring Cycle <-+--		uint_t |
+ *	|			    |			 +---------------------+
+ *	| usba_hcdi_ops_t *	   -+-> USBA Ops Vector			      ^
+ *	| usb_dev_dscr_t	   -+-> USB Virtual Device Descriptor	      |
+ *	| usb_ss_hub_descr_t	   -+-> USB Virtual Hub Descriptor	      |
+ *	| usba_pipe_handle_data_t * +-> Interrupt polling client	      |
+ *	| usb_intr_req_t	   -+-> Interrupt polling request	      |
+ *	| uint32_t		  --+-> Interrupt polling device mask	      |
+ *	| list_t		  --+-> Pipe List (Active Users)	      |
+ *	| list_t		  --+-------------------+		      |
+ *	+---------------------------+			|		      ^
+ *							|		      |
+ *							v		      |
+ *     +-------------------------------+	     +---------------+	      |
+ *     | USB Device		       |------------>| USB Device    |--> ... |
+ *     | xhci_device_t		       |	     | xhci_device_t |	      |
+ *     |			       |	     +---------------+	      |
+ *     | usb_port_t		     --+-> USB Port plugged into	      |
+ *     | uint8_t		     --+-> Slot Number			      |
+ *     | boolean_t		     --+-> Address Assigned		      |
+ *     | usba_device_t *	     --+-> USBA Device State		      |
+ *     | xhci_dma_buffer_t	     --+-> Input Context DMA Buffer	      |
+ *     | xhci_input_context_t *      --+-> Input Context KVA		      |
+ *     | xhci_slot_contex_t *	     --+-> Input Slot Context KVA	      |
+ *     | xhci_endpoint_context_t *[] --+-> Input Endpoint Context KVA	      |
+ *     | xhci_dma_buffer_t	     --+-> Output Context DMA Buffer	      |
+ *     | xhci_slot_context_t *	     --+-> Output Slot Context KVA	      ^
+ *     | xhci_endpoint_context_t *[] --+-> Output Endpoint Context KVA	      |
+ *     | xhci_endpoint_t *[]	     --+-> Endpoint Tracking ---+	      |
+ *     +-------------------------------+			|	      |
+ *								|	      |
+ *								v	      |
+ *     +------------------------------+		   +-----------------+	      |
+ *     | Endpoint Data		      |----------->| Endpoint Data   |--> ... |
+ *     | xhci_endpoint_t	      |		   | xhci_endpoint_t |	      |
+ *     |			      |		   +-----------------+	      |
+ *     | int			    --+-> Endpoint Number		      |
+ *     | int			    --+-> Endpoint Type			      |
+ *     | xhci_endpoint_state_t	    --+-> Endpoint State		      |
+ *     | timeout_id_t		    --+-> Endpoint Timeout State	      |
+ *     | usba_pipe_handle_data_t *  --+-> USBA Client Handle		      |
+ *     | xhci_ring_t		    --+-> Endpoint I/O Ring  -------->--------+
+ *     | list_t			    --+-> Transfer List --------+
+ *     +------------------------------+				|
+ *								v
+ *     +-------------------------+		    +--------------------+
+ *     | Transfer Structure	 |----------------->| Transfer Structure |-> ...
+ *     | xhci_transfer_t	 |		    | xhci_transfer_t	 |
+ *     |			 |		    +--------------------+
  *     | xhci_dma_buffer_t     --+-> I/O DMA Buffer
- *     | uint_t                --+-> Number of TRBs
- *     | uint_t                --+-> Short transfer data
- *     | uint_t                --+-> Timeout seconds remaining
- *     | usb_cr_t              --+-> USB Transfer return value
- *     | boolean_t             --+-> Data direction
- *     | xhci_trb_t *          --+-> Host-order transfer requests for I/O
+ *     | uint_t		       --+-> Number of TRBs
+ *     | uint_t		       --+-> Short transfer data
+ *     | uint_t		       --+-> Timeout seconds remaining
+ *     | usb_cr_t	       --+-> USB Transfer return value
+ *     | boolean_t	       --+-> Data direction
+ *     | xhci_trb_t *	       --+-> Host-order transfer requests for I/O
  *     | usb_isoc_pkt_descr_t * -+-> Isochronous only response data
- *     | usb_opaque_t          --+-> USBA Request Handle
+ *     | usb_opaque_t	       --+-> USBA Request Handle
  *     +-------------------------+
  *
  * -------------
@@ -1013,10 +1014,10 @@
 	ddi_fm_error_t de;
 
 	/*
-	 * Treat the case where we can't check as fine so we can treat the code
+	 * Treat cases where we can't check as fine so we can treat the code
 	 * more simply.
 	 */
-	if (!DDI_FM_ACC_ERR_CAP(xhcip->xhci_fm_caps))
+	if (quiesce_active || !DDI_FM_ACC_ERR_CAP(xhcip->xhci_fm_caps))
 		return (DDI_FM_OK);
 
 	ddi_fm_acc_err_get(xhcip->xhci_regs_handle, &de, DDI_FME_VERSION);
@@ -1971,6 +1972,18 @@
 	return (DDI_SUCCESS);
 }
 
+/* QUIESCE(9E) to support fast reboot */
+int
+xhci_quiesce(dev_info_t *dip)
+{
+	xhci_t *xhcip;
+
+	xhcip = ddi_get_soft_state(xhci_soft_state, ddi_get_instance(dip));
+
+	return (xhci_controller_stop(xhcip) == 0 &&
+	    xhci_controller_reset(xhcip) == 0 ? DDI_SUCCESS : DDI_FAILURE);
+}
+
 static int
 xhci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 {
@@ -2183,7 +2196,7 @@
 	&xhci_cb_ops,			/* devo_cb_ops */
 	&usba_hubdi_busops,		/* devo_bus_ops */
 	usba_hubdi_root_hub_power,	/* devo_power */
-	ddi_quiesce_not_supported 	/* devo_quiesce */
+	xhci_quiesce			/* devo_quiesce */
 };
 
 static struct modldrv xhci_modldrv = {
