summaryrefslogtreecommitdiffstats
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2005-09-11 04:09:44 +0000
committerimp <imp@FreeBSD.org>2005-09-11 04:09:44 +0000
commit638a6dba078509fb071a5969416731f4577a7544 (patch)
tree3c2251890438df6763e33c2af0a969d12497a8b7 /sys/dev/pci
parent312435e93341532299b80c689c3b8d8f4f9b3fce (diff)
downloadFreeBSD-src-638a6dba078509fb071a5969416731f4577a7544.zip
FreeBSD-src-638a6dba078509fb071a5969416731f4577a7544.tar.gz
Change hw.pci.do_powerstate from a boolean to a range. 0 means the
same as today: do no power management. 1 means be conservative about what you power down (any device class that has caused problems gets added here). 2 means be agressive about what gets powered down (any device class that's fundamental to the system is here). 3 means power them all down, reguardless. The default is 1. The effect in the default system is to add mass storage devices to the list that we don't power down. From all the pciconf -l lists that I've seen for the aac and amr issue, the bad device has been a mass storage device class. This is an attempt at a compromise between the very small number of systems that have extreme issues with powerdown, and the very large number of systems that gain real benefits from powerdown (I get about 20% more battery life when I attach a minimal set of drivers on my Sony). Hopefully it will strike the proper balance. MFC After: 3 days (before next beta)
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/pci.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 52fcdfe..0d8bd1c 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -187,8 +187,14 @@ static int pci_do_powerstate = 1;
TUNABLE_INT("hw.pci.do_powerstate", &pci_do_powerstate);
SYSCTL_INT(_hw_pci, OID_AUTO, do_powerstate, CTLFLAG_RW,
&pci_do_powerstate, 1,
- "Power down devices into D3 state when no driver attaches to them.\n\
-Otherwise, leave the device in D0 state when no driver attaches.");
+ "Controls the behvior of the pci driver when it encounters\n\
+devices which no driver claims. Set to 0 causes the pci to leave\n\
+the device in D0. Set to 1 causes pci to conservatively devices\n\
+into D3 state. These are devices which have had issues in the past.\n\
+Set to 2 causes the bus driver to agressively place devices into D3 state.\n\
+The only devices it excludes are devices for which no drivers generally\n\
+exist in FreeBSD. Set to 3 causes the bus driver to place all unattached\n\
+devices into D3 state.");
/* Find a device_t by bus/slot/function */
@@ -2003,18 +2009,31 @@ pci_cfg_save(device_t dev, struct pci_devinfo *dinfo, int setstate)
* power the device down on a reattach.
*/
cls = pci_get_class(dev);
- if (setstate && cls != PCIC_DISPLAY && cls != PCIC_MEMORY &&
- cls != PCIC_BASEPERIPH) {
- /*
- * PCI spec says we can only go into D3 state from D0 state.
- * Transition from D[12] into D0 before going to D3 state.
- */
- ps = pci_get_powerstate(dev);
- if (ps != PCI_POWERSTATE_D0 && ps != PCI_POWERSTATE_D3) {
- pci_set_powerstate(dev, PCI_POWERSTATE_D0);
- }
- if (pci_get_powerstate(dev) != PCI_POWERSTATE_D3) {
- pci_set_powerstate(dev, PCI_POWERSTATE_D3);
- }
+ if (!setstate)
+ return;
+ switch (pci_do_powerstate)
+ {
+ case 0: /* NO powerdown at all */
+ return;
+ case 1: /* Conservative about what to power down */
+ if (cls == PCIC_STORAGE)
+ return;
+ /*FALLTHROUGH*/
+ case 2: /* Agressive about what to power down */
+ if (cls == PCIC_DISPLAY || cls == PCIC_MEMORY ||
+ cls == PCIC_BASEPERIPH)
+ return;
+ /*FALLTHROUGH*/
+ case 3: /* Power down everything */
+ break;
}
+ /*
+ * PCI spec says we can only go into D3 state from D0 state.
+ * Transition from D[12] into D0 before going to D3 state.
+ */
+ ps = pci_get_powerstate(dev);
+ if (ps != PCI_POWERSTATE_D0 && ps != PCI_POWERSTATE_D3)
+ pci_set_powerstate(dev, PCI_POWERSTATE_D0);
+ if (pci_get_powerstate(dev) != PCI_POWERSTATE_D3)
+ pci_set_powerstate(dev, PCI_POWERSTATE_D3);
}
OpenPOWER on IntegriCloud