Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108674921
D48384.id149102.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D48384.id149102.diff
View Options
diff --git a/sys/compat/linuxkpi/common/include/linux/pci.h b/sys/compat/linuxkpi/common/include/linux/pci.h
--- a/sys/compat/linuxkpi/common/include/linux/pci.h
+++ b/sys/compat/linuxkpi/common/include/linux/pci.h
@@ -212,11 +212,11 @@
typedef int pci_power_t;
-#define PCI_D0 PCI_POWERSTATE_D0
-#define PCI_D1 PCI_POWERSTATE_D1
-#define PCI_D2 PCI_POWERSTATE_D2
-#define PCI_D3hot PCI_POWERSTATE_D3
-#define PCI_D3cold 4
+#define PCI_D0 PCI_POWERSTATE_D0
+#define PCI_D1 PCI_POWERSTATE_D1
+#define PCI_D2 PCI_POWERSTATE_D2
+#define PCI_D3hot PCI_POWERSTATE_D3_HOT
+#define PCI_D3cold PCI_POWERSTATE_D3_COLD
#define PCI_POWER_ERROR PCI_POWERSTATE_UNKNOWN
diff --git a/sys/contrib/dev/acpica/include/actypes.h b/sys/contrib/dev/acpica/include/actypes.h
--- a/sys/contrib/dev/acpica/include/actypes.h
+++ b/sys/contrib/dev/acpica/include/actypes.h
@@ -741,9 +741,11 @@
#define ACPI_STATE_D0 (UINT8) 0
#define ACPI_STATE_D1 (UINT8) 1
#define ACPI_STATE_D2 (UINT8) 2
-#define ACPI_STATE_D3 (UINT8) 3
-#define ACPI_D_STATES_MAX ACPI_STATE_D3
-#define ACPI_D_STATE_COUNT 4
+#define ACPI_STATE_D3_HOT (UINT8) 3
+#define ACPI_STATE_D3_COLD (UINT8) 4
+#define ACPI_STATE_D3 ACPI_STATE_D3_COLD
+#define ACPI_D_STATES_MAX ACPI_STATE_D3_COLD
+#define ACPI_D_STATE_COUNT 5
#define ACPI_STATE_C0 (UINT8) 0
#define ACPI_STATE_C1 (UINT8) 1
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -2080,12 +2080,13 @@
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
--- 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")
@@ -240,12 +237,13 @@
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
--- a/sys/dev/acpica/acpi_powerres.c
+++ b/sys/dev/acpica/acpi_powerres.c
@@ -299,7 +299,7 @@
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 @@
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 @@
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 @@
*/
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 @@
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 @@
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 @@
*/
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
--- a/sys/dev/acpica/acpivar.h
+++ b/sys/dev/acpica/acpivar.h
@@ -488,6 +488,15 @@
return (0);
}
+static __inline const char *
+acpi_d_state_to_str(int state)
+{
+ const char *strs[ACPI_D_STATE_COUNT] = {"D0", "D1", "D2", "D3", "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
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -81,6 +81,9 @@
#include <dev/iommu/iommu.h>
+#include <contrib/dev/acpica/include/acpi.h>
+#include <dev/acpica/acpivar.h>
+
#include "pcib_if.h"
#include "pci_if.h"
@@ -2846,8 +2849,8 @@
}
if (bootverbose)
- pci_printf(cfg, "Transition from D%d to D%d\n", oldstate,
- state);
+ pci_printf(cfg, "Transition from %s to %s\n",
+ acpi_d_state_to_str(oldstate), acpi_d_state_to_str(state));
PCI_WRITE_CONFIG(dev, child, cfg->pp.pp_status, status, 2);
if (delay)
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -501,22 +501,25 @@
/*
* 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_UNKNOWN -1
static __inline int
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 28, 5:52 AM (2 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16253275
Default Alt Text
D48384.id149102.diff (10 KB)
Attached To
Mode
D48384: acpi_powerres: D3cold support and `acpi_d_state_to_str`
Attached
Detach File
Event Timeline
Log In to Comment