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",