diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/acpica/acpi.c | 9 | ||||
-rw-r--r-- | sys/dev/acpica/acpi_pci.c | 12 | ||||
-rw-r--r-- | sys/dev/acpica/acpi_powerres.c | 58 | ||||
-rw-r--r-- | sys/dev/acpica/acpivar.h | 10 | ||||
-rw-r--r-- | sys/dev/pci/pci.c | 5 | ||||
-rw-r--r-- | sys/dev/pci/pcivar.h | 39 | ||||
-rw-r--r-- | sys/dev/sdio/sdiob.c | 7 |
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, |