On Wednesday 29 December 2010 18:10:16 Mark Kettenis wrote: > For those that have problems with (acpi) suspend/resume that can be > fixed by setting pci_dopm to 0, please test the diff below. This > fixes a flaw in the powermanagement code where we would disable > devices (and in particular PCI-PCI bridges) even if those devices > don't support powermanagement. > > Also, it would be interesting if people with working apm > suspend/resume could test this diff and set pci_dopm to 1. > > Thanks, > > Mark
With this suspend/resume now works without disabling PCI power management with the ThinkPad X100e. > > Index: pci.c > =================================================================== > RCS file: /cvs/src/sys/dev/pci/pci.c,v > retrieving revision 1.87 > diff -u -p -r1.87 pci.c > --- pci.c 4 Dec 2010 17:08:20 -0000 1.87 > +++ pci.c 29 Dec 2010 23:02:29 -0000 > @@ -215,7 +215,7 @@ void > pci_suspend(struct pci_softc *sc) > { > struct pci_dev *pd; > - pcireg_t bhlc, csr; > + pcireg_t bhlc; > int i; > > LIST_FOREACH(pd, &sc->sc_devs, pd_next) { > @@ -240,18 +240,7 @@ pci_suspend(struct pci_softc *sc) > PCI_INTERRUPT_REG); > > if (pci_dopm) { > - /* > - * Place the device into D3. The PCI Power > - * Management spec says we should disable I/O > - * and memory space as well as bus mastering > - * before we do so. > - */ > - csr = pd->pd_csr; > - csr &= ~PCI_COMMAND_IO_ENABLE; > - csr &= ~PCI_COMMAND_MEM_ENABLE; > - csr &= ~PCI_COMMAND_MASTER_ENABLE; > - pci_conf_write(sc->sc_pc, pd->pd_tag, > - PCI_COMMAND_STATUS_REG, csr); > + /* Place the device into D3. */ > pd->pd_pmcsr_state = pci_get_powerstate(sc->sc_pc, > pd->pd_tag); > pci_set_powerstate(sc->sc_pc, pd->pd_tag, > @@ -567,6 +556,19 @@ pci_set_powerstate(pci_chipset_tag_t pc, > int offset; > > if (pci_get_capability(pc, tag, PCI_CAP_PWRMGMT, &offset, 0)) { > + if (state == PCI_PMCSR_STATE_D3) { > + /* > + * The PCI Power Management spec says we > + * should disable I/O and memory space as well > + * as bus mastering before we place the device > + * into D3. > + */ > + reg = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); > + reg &= ~PCI_COMMAND_IO_ENABLE; > + reg &= ~PCI_COMMAND_MEM_ENABLE; > + reg &= ~PCI_COMMAND_MASTER_ENABLE; > + pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, reg); > + } > reg = pci_conf_read(pc, tag, offset + PCI_PMCSR); > if ((reg & PCI_PMCSR_STATE_MASK) != state) { > pci_conf_write(pc, tag, offset + PCI_PMCSR, > Index: ppb.c > =================================================================== > RCS file: /cvs/src/sys/dev/pci/ppb.c,v > retrieving revision 1.46 > diff -u -p -r1.46 ppb.c > --- ppb.c 25 Sep 2010 19:23:39 -0000 1.46 > +++ ppb.c 29 Dec 2010 23:02:29 -0000 > @@ -346,7 +346,7 @@ ppbactivate(struct device *self, int act > struct ppb_softc *sc = (void *)self; > pci_chipset_tag_t pc = sc->sc_pc; > pcitag_t tag = sc->sc_tag; > - pcireg_t blr, csr, reg; > + pcireg_t blr, reg; > int rv = 0; > > switch (act) { > @@ -367,17 +367,7 @@ ppbactivate(struct device *self, int act > sc->sc_cap_off + PCI_PCIE_SLCSR); > > if (pci_dopm) { > - /* > - * Place the bridge into D3. The PCI Power > - * Management spec says we should disable I/O > - * and memory space as well as bus mastering > - * before we do so. > - */ > - csr = sc->sc_csr; > - csr &= ~PCI_COMMAND_IO_ENABLE; > - csr &= ~PCI_COMMAND_MEM_ENABLE; > - csr &= ~PCI_COMMAND_MASTER_ENABLE; > - pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr); > + /* Place the bridge into D3. */ > sc->sc_pmcsr_state = pci_get_powerstate(pc, tag); > pci_set_powerstate(pc, tag, PCI_PMCSR_STATE_D3); > } -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.