Print this page
xhci_Quiesce

@@ -1088,11 +1088,12 @@
 {
         uint_t i;
 
         for (i = 0; i < tries; i++) {
                 uint32_t val = xhci_get32(xhcip, rt, reg);
-                if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
+                if (!quiesce_active && xhci_check_regs_acc(xhcip)
+                    != DDI_FM_OK) {
                         ddi_fm_service_impact(xhcip->xhci_dip,
                             DDI_SERVICE_LOST);
                         return (EIO);
                 }
 

@@ -1571,20 +1572,20 @@
 xhci_controller_stop(xhci_t *xhcip)
 {
         uint32_t cmdreg;
 
         cmdreg = xhci_get32(xhcip, XHCI_R_OPER, XHCI_USBCMD);
-        if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
+        if (!quiesce_active && xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
                 xhci_error(xhcip, "failed to read USB Command register: "
                     "encountered fatal FM register error");
                 ddi_fm_service_impact(xhcip->xhci_dip, DDI_SERVICE_LOST);
                 return (EIO);
         }
 
         cmdreg &= ~(XHCI_CMD_RS | XHCI_CMD_INTE);
         xhci_put32(xhcip, XHCI_R_OPER, XHCI_USBCMD, cmdreg);
-        if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
+        if (!quiesce_active && xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
                 xhci_error(xhcip, "failed to write USB Command register: "
                     "encountered fatal FM register error");
                 ddi_fm_service_impact(xhcip->xhci_dip, DDI_SERVICE_LOST);
                 return (EIO);
         }

@@ -1603,20 +1604,20 @@
 {
         int ret;
         uint32_t cmdreg;
 
         cmdreg = xhci_get32(xhcip, XHCI_R_OPER, XHCI_USBCMD);
-        if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
+        if (!quiesce_active && xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
                 xhci_error(xhcip, "failed to read USB Command register for "
                     "reset: encountered fatal FM register error");
                 ddi_fm_service_impact(xhcip->xhci_dip, DDI_SERVICE_LOST);
                 return (EIO);
         }
 
         cmdreg |= XHCI_CMD_HCRST;
         xhci_put32(xhcip, XHCI_R_OPER, XHCI_USBCMD, cmdreg);
-        if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
+        if (!quiesce_active && xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
                 xhci_error(xhcip, "failed to write USB Command register for "
                     "reset: encountered fatal FM register error");
                 ddi_fm_service_impact(xhcip->xhci_dip, DDI_SERVICE_LOST);
                 return (EIO);
         }

@@ -1969,10 +1970,22 @@
         ddi_soft_state_free(xhci_soft_state, inst);
 
         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)
 {
         int ret, inst, route;
         xhci_t *xhcip;

@@ -2181,11 +2194,11 @@
         xhci_detach,                    /* devo_detach */
         nodev,                          /* devo_reset */
         &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 = {
         &mod_driverops,
         "USB xHCI Driver",