aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/acpica/acpi.c9
-rw-r--r--sys/dev/acpica/acpi_pci.c12
-rw-r--r--sys/dev/acpica/acpi_powerres.c58
-rw-r--r--sys/dev/acpica/acpivar.h10
-rw-r--r--sys/dev/pci/pci.c5
-rw-r--r--sys/dev/pci/pcivar.h39
-rw-r--r--sys/dev/sdio/sdiob.c7
7 files changed, 95 insertions, 45 deletions
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index f2ff1d59ccc7..a2159b12876f 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -2139,12 +2139,13 @@ acpi_set_powerstate(device_t child, int state)
status = acpi_pwr_switch_consumer(h, state);
if (ACPI_SUCCESS(status)) {
if (bootverbose)
- device_printf(child, "set ACPI power state D%d on %s\n",
- state, acpi_name(h));
+ device_printf(child, "set ACPI power state %s on %s\n",
+ acpi_d_state_to_str(state), acpi_name(h));
} else if (status != AE_NOT_FOUND)
device_printf(child,
- "failed to set ACPI power state D%d on %s: %s\n", state,
- acpi_name(h), AcpiFormatException(status));
+ "failed to set ACPI power state %s on %s: %s\n",
+ acpi_d_state_to_str(state), acpi_name(h),
+ AcpiFormatException(status));
return (0);
}
diff --git a/sys/dev/acpica/acpi_pci.c b/sys/dev/acpica/acpi_pci.c
index 646295f9eecc..1912350bbc48 100644
--- a/sys/dev/acpica/acpi_pci.c
+++ b/sys/dev/acpica/acpi_pci.c
@@ -53,9 +53,6 @@
#include <dev/iommu/iommu.h>
-#include "pcib_if.h"
-#include "pci_if.h"
-
/* Hooks for the ACPI CA debugging infrastructure. */
#define _COMPONENT ACPI_BUS
ACPI_MODULE_NAME("PCI")
@@ -266,12 +263,13 @@ acpi_pci_set_powerstate_method(device_t dev, device_t child, int state)
status = acpi_pwr_switch_consumer(h, state);
if (ACPI_SUCCESS(status)) {
if (bootverbose)
- device_printf(dev, "set ACPI power state D%d on %s\n",
- state, acpi_name(h));
+ device_printf(dev, "set ACPI power state %s on %s\n",
+ acpi_d_state_to_str(state), acpi_name(h));
} else if (status != AE_NOT_FOUND)
device_printf(dev,
- "failed to set ACPI power state D%d on %s: %s\n",
- state, acpi_name(h), AcpiFormatException(status));
+ "failed to set ACPI power state %s on %s: %s\n",
+ acpi_d_state_to_str(state), acpi_name(h),
+ AcpiFormatException(status));
if (old_state > state && pci_do_power_resume)
error = pci_set_powerstate_method(dev, child, state);
diff --git a/sys/dev/acpica/acpi_powerres.c b/sys/dev/acpica/acpi_powerres.c
index 0f2a25b1d02b..29d1690f1bdd 100644
--- a/sys/dev/acpica/acpi_powerres.c
+++ b/sys/dev/acpica/acpi_powerres.c
@@ -299,7 +299,7 @@ acpi_pwr_switch_consumer(ACPI_HANDLE consumer, int state)
ACPI_BUFFER reslist_buffer;
ACPI_OBJECT *reslist_object;
ACPI_STATUS status;
- char *method_name, *reslist_name;
+ char *method_name, *reslist_name = NULL;
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
@@ -318,9 +318,26 @@ acpi_pwr_switch_consumer(ACPI_HANDLE consumer, int state)
panic("acpi added power consumer but can't find it");
}
- /* Check for valid transitions. We can only go to D0 from D3. */
+ /* Stop here if we're already at the target D-state. */
+ if (pc->ac_state == state) {
+ status = AE_OK;
+ goto out;
+ }
+
+ /*
+ * Check for valid transitions. From D3hot or D3cold, we can only go to D0.
+ * The exception to this is going from D3hot to D3cold or the other way
+ * around. This is because they both use _PS3, so the only difference when
+ * doing these transitions is whether or not the power resources for _PR3
+ * are on for devices which support D3cold, and turning these power
+ * resources on/off is always perfectly fine (ACPI 7.3.11).
+ */
status = AE_BAD_PARAMETER;
- if (pc->ac_state == ACPI_STATE_D3 && state != ACPI_STATE_D0)
+ if (pc->ac_state == ACPI_STATE_D3_HOT && state != ACPI_STATE_D0 &&
+ state != ACPI_STATE_D3_COLD)
+ goto out;
+ if (pc->ac_state == ACPI_STATE_D3_COLD && state != ACPI_STATE_D0 &&
+ state != ACPI_STATE_D3_HOT)
goto out;
/* Find transition mechanism(s) */
@@ -337,15 +354,20 @@ acpi_pwr_switch_consumer(ACPI_HANDLE consumer, int state)
method_name = "_PS2";
reslist_name = "_PR2";
break;
- case ACPI_STATE_D3:
+ case ACPI_STATE_D3_HOT:
method_name = "_PS3";
reslist_name = "_PR3";
break;
+ case ACPI_STATE_D3_COLD:
+ method_name = "_PS3";
+ reslist_name = NULL;
+ break;
default:
goto out;
}
- ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "setup to switch %s D%d -> D%d\n",
- acpi_name(consumer), pc->ac_state, state));
+ ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "setup to switch %s %s -> %s\n",
+ acpi_name(consumer), acpi_d_state_to_str(pc->ac_state),
+ acpi_d_state_to_str(state)));
/*
* Verify that this state is supported, ie. one of method or
@@ -359,7 +381,8 @@ acpi_pwr_switch_consumer(ACPI_HANDLE consumer, int state)
*/
if (ACPI_FAILURE(AcpiGetHandle(consumer, method_name, &method_handle)))
method_handle = NULL;
- if (ACPI_FAILURE(AcpiGetHandle(consumer, reslist_name, &reslist_handle)))
+ if (reslist_name == NULL ||
+ ACPI_FAILURE(AcpiGetHandle(consumer, reslist_name, &reslist_handle)))
reslist_handle = NULL;
if (reslist_handle == NULL && method_handle == NULL) {
if (state == ACPI_STATE_D0) {
@@ -367,9 +390,12 @@ acpi_pwr_switch_consumer(ACPI_HANDLE consumer, int state)
status = AE_OK;
goto out;
}
- if (state != ACPI_STATE_D3) {
+ if (state == ACPI_STATE_D3_COLD)
+ state = ACPI_STATE_D3_HOT;
+ if (state != ACPI_STATE_D3_HOT) {
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
- "attempt to set unsupported state D%d\n", state));
+ "attempt to set unsupported state %s\n",
+ acpi_d_state_to_str(state)));
goto out;
}
@@ -380,21 +406,23 @@ acpi_pwr_switch_consumer(ACPI_HANDLE consumer, int state)
if (ACPI_FAILURE(AcpiGetHandle(consumer, "_PR0", &pr0_handle))) {
status = AE_NOT_FOUND;
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
- "device missing _PR0 (desired state was D%d)\n", state));
+ "device missing _PR0 (desired state was %s)\n",
+ acpi_d_state_to_str(state)));
goto out;
}
reslist_buffer.Length = ACPI_ALLOCATE_BUFFER;
status = AcpiEvaluateObject(pr0_handle, NULL, NULL, &reslist_buffer);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
- "can't evaluate _PR0 for device %s, state D%d\n",
- acpi_name(consumer), state));
+ "can't evaluate _PR0 for device %s, state %s\n",
+ acpi_name(consumer), acpi_d_state_to_str(state)));
goto out;
}
reslist_object = (ACPI_OBJECT *)reslist_buffer.Pointer;
if (!ACPI_PKG_VALID(reslist_object, 1)) {
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
- "invalid package object for state D%d\n", state));
+ "invalid package object for state %s\n",
+ acpi_d_state_to_str(state)));
status = AE_TYPE;
goto out;
}
@@ -450,8 +478,8 @@ acpi_pwr_switch_consumer(ACPI_HANDLE consumer, int state)
*/
if (ACPI_FAILURE(status = acpi_pwr_switch_power())) {
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
- "failed to switch resources from %s to D%d\n",
- acpi_name(consumer), state));
+ "failed to switch resources from %s to %s\n",
+ acpi_name(consumer), acpi_d_state_to_str(state)));
/* XXX is this appropriate? Should we return to previous state? */
goto out;
diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h
index 106ec9038820..6887f080311d 100644
--- a/sys/dev/acpica/acpivar.h
+++ b/sys/dev/acpica/acpivar.h
@@ -517,6 +517,16 @@ acpi_get_verbose(struct acpi_softc *sc)
return (0);
}
+static __inline const char *
+acpi_d_state_to_str(int state)
+{
+ const char *strs[ACPI_D_STATE_COUNT] = {"D0", "D1", "D2", "D3hot",
+ "D3cold"};
+
+ MPASS(state >= ACPI_STATE_D0 && state <= ACPI_D_STATES_MAX);
+ return (strs[state]);
+}
+
char *acpi_name(ACPI_HANDLE handle);
int acpi_avoid(ACPI_HANDLE handle);
int acpi_disabled(char *subsys);
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index f94438cda041..9e43a4c1909f 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -2896,8 +2896,9 @@ pci_set_powerstate_method(device_t dev, device_t child, int state)
}
if (bootverbose)
- pci_printf(cfg, "Transition from D%d to D%d\n", oldstate,
- state);
+ pci_printf(cfg, "Transition from %s to %s\n",
+ pci_powerstate_to_str(oldstate),
+ pci_powerstate_to_str(state));
PCI_WRITE_CONFIG(dev, child, cfg->pp.pp_location + PCIR_POWER_STATUS,
status, 2);
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
index d1b7d28eae91..4abb5e977346 100644
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -497,24 +497,39 @@ pci_is_vga_memory_range(rman_res_t start, rman_res_t end)
/*
* PCI power states are as defined by ACPI:
*
- * D0 State in which device is on and running. It is receiving full
- * power from the system and delivering full functionality to the user.
- * D1 Class-specific low-power state in which device context may or may not
- * be lost. Buses in D1 cannot do anything to the bus that would force
- * devices on that bus to lose context.
- * D2 Class-specific low-power state in which device context may or may
- * not be lost. Attains greater power savings than D1. Buses in D2
- * can cause devices on that bus to lose some context. Devices in D2
- * must be prepared for the bus to be in D2 or higher.
- * D3 State in which the device is off and not running. Device context is
- * lost. Power can be removed from the device.
+ * D0 State in which device is on and running. It is receiving full
+ * power from the system and delivering full functionality to the user.
+ * D1 Class-specific low-power state in which device context may or may not
+ * be lost. Buses in D1 cannot do anything to the bus that would force
+ * devices on that bus to lose context.
+ * D2 Class-specific low-power state in which device context may or may
+ * not be lost. Attains greater power savings than D1. Buses in D2
+ * can cause devices on that bus to lose some context. Devices in D2
+ * must be prepared for the bus to be in D2 or higher.
+ * D3hot State in which the device is off and not running. Device context is
+ * lost. Power can be removed from the device.
+ * D3cold Same as D3hot, but power has been removed from the device.
*/
#define PCI_POWERSTATE_D0 0
#define PCI_POWERSTATE_D1 1
#define PCI_POWERSTATE_D2 2
-#define PCI_POWERSTATE_D3 3
+#define PCI_POWERSTATE_D3_HOT 3
+#define PCI_POWERSTATE_D3_COLD 4
+#define PCI_POWERSTATE_D3 PCI_POWERSTATE_D3_COLD
+#define PCI_POWERSTATE_MAX PCI_POWERSTATE_D3_COLD
+#define PCI_POWERSTATE_COUNT 5
#define PCI_POWERSTATE_UNKNOWN -1
+static __inline const char *
+pci_powerstate_to_str(int state)
+{
+ const char *strs[PCI_POWERSTATE_COUNT] = {"D0", "D1", "D2", "D3hot",
+ "D3cold"};
+
+ MPASS(state >= PCI_POWERSTATE_D0 && state <= PCI_POWERSTATE_MAX);
+ return (strs[state]);
+}
+
static __inline int
pci_set_powerstate(device_t dev, int state)
{
diff --git a/sys/dev/sdio/sdiob.c b/sys/dev/sdio/sdiob.c
index 4ec2058fa2e4..cb2cc0da6b77 100644
--- a/sys/dev/sdio/sdiob.c
+++ b/sys/dev/sdio/sdiob.c
@@ -150,7 +150,7 @@ sdiob_rw_direct_sc(struct sdiob_softc *sc, uint8_t fn, uint32_t addr, bool wr,
sc->ccb = xpt_alloc_ccb();
else
memset(sc->ccb, 0, sizeof(*sc->ccb));
- xpt_setup_ccb(&sc->ccb->ccb_h, sc->periph->path, CAM_PRIORITY_NONE);
+ xpt_setup_ccb(&sc->ccb->ccb_h, sc->periph->path, CAM_PRIORITY_NORMAL);
CAM_DEBUG(sc->ccb->ccb_h.path, CAM_DEBUG_TRACE,
("%s(fn=%d, addr=%#02x, wr=%d, *val=%#02x)\n", __func__,
fn, addr, wr, *val));
@@ -250,7 +250,7 @@ sdiob_rw_extended_cam(struct sdiob_softc *sc, uint8_t fn, uint32_t addr,
sc->ccb = xpt_alloc_ccb();
else
memset(sc->ccb, 0, sizeof(*sc->ccb));
- xpt_setup_ccb(&sc->ccb->ccb_h, sc->periph->path, CAM_PRIORITY_NONE);
+ xpt_setup_ccb(&sc->ccb->ccb_h, sc->periph->path, CAM_PRIORITY_NORMAL);
CAM_DEBUG(sc->ccb->ccb_h.path, CAM_DEBUG_TRACE,
("%s(fn=%d addr=%#0x wr=%d b_count=%u blksz=%u buf=%p incr=%d)\n",
__func__, fn, addr, wr, b_count, blksz, buffer, incaddr));
@@ -977,9 +977,6 @@ sdiobdiscover(void *context, int pending)
if (sc->ccb == NULL)
sc->ccb = xpt_alloc_ccb();
- else
- memset(sc->ccb, 0, sizeof(*sc->ccb));
- xpt_setup_ccb(&sc->ccb->ccb_h, periph->path, CAM_PRIORITY_NONE);
/*
* Read CCCR and FBR of each function, get manufacturer and device IDs,