re-factor the pci powestate api. reviewed by gimpy

This commit is contained in:
christos 2006-06-17 23:34:26 +00:00
parent 99d15da99a
commit 63bbcb495a
24 changed files with 399 additions and 582 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ahd_pci.c,v 1.22 2006/03/08 23:46:27 lukem Exp $ */
/* $NetBSD: ahd_pci.c,v 1.23 2006/06/17 23:34:26 christos Exp $ */
/*
* Product specific probe and attach routines for:
@ -49,7 +49,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ahd_pci.c,v 1.22 2006/03/08 23:46:27 lukem Exp $");
__KERNEL_RCSID(0, "$NetBSD: ahd_pci.c,v 1.23 2006/06/17 23:34:26 christos Exp $");
#define AHD_PCI_IOADDR PCI_MAPREG_START /* I/O Address */
#define AHD_PCI_MEMADDR (PCI_MAPREG_START + 4) /* Mem I/O Address */
@ -310,8 +310,6 @@ ahd_pci_attach(struct device *parent, struct device *self, void *aux)
int error;
pcireg_t subid;
uint16_t subvendor;
int pci_pwrmgmt_cap_reg;
int pci_pwrmgmt_csr_reg;
pcireg_t reg;
int ioh_valid, ioh2_valid, memh_valid;
pcireg_t memtype;
@ -480,22 +478,13 @@ ahd_pci_attach(struct device *parent, struct device *self, void *aux)
aprint_normal("\n");
aprint_naive("\n");
/*
* Set Power State D0.
*/
if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PWRMGMT,
&pci_pwrmgmt_cap_reg, 0)) {
pci_pwrmgmt_csr_reg = pci_pwrmgmt_cap_reg + 4;
reg = pci_conf_read(pa->pa_pc, pa->pa_tag,
pci_pwrmgmt_csr_reg);
if ((reg & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_STATE_D0) {
pci_conf_write(pa->pa_pc, pa->pa_tag, pci_pwrmgmt_csr_reg,
(reg & ~PCI_PMCSR_STATE_MASK) |
PCI_PMCSR_STATE_D0);
}
}
/* power up chip */
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, ahd,
pci_activate_null)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", ahd->sc_dev.dv_xname,
error);
return;
}
/*
* Should we bother disabling 39Bit addressing
* based on installed memory?

View File

@ -1,4 +1,4 @@
/* $NetBSD: auich.c,v 1.107 2006/04/27 12:21:39 jmcneill Exp $ */
/* $NetBSD: auich.c,v 1.108 2006/06/17 23:34:26 christos Exp $ */
/*-
* Copyright (c) 2000, 2004, 2005 The NetBSD Foundation, Inc.
@ -118,7 +118,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: auich.c,v 1.107 2006/04/27 12:21:39 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: auich.c,v 1.108 2006/06/17 23:34:26 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -1561,8 +1561,6 @@ static void
auich_powerhook(int why, void *addr)
{
struct auich_softc *sc;
const int d0 = PCI_PWR_D0;
const int d3 = PCI_PWR_D3;
int rv;
sc = (struct auich_softc *)addr;
@ -1584,7 +1582,11 @@ auich_powerhook(int why, void *addr)
if (sc->sc_ih != NULL)
pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
rv = pci_powerstate(sc->sc_pc, sc->sc_pt, &d3, &sc->sc_powerstate);
rv = pci_get_powerstate(sc->sc_pc, sc->sc_pt, &sc->sc_powerstate);
if (rv)
aprint_error("%s: unable to get power state (err=%d)\n",
sc->sc_dev.dv_xname, rv);
rv = pci_set_powerstate(sc->sc_pc, sc->sc_pt, PCI_PMCSR_STATE_D3);
if (rv)
aprint_error("%s: unable to set power state (err=%d)\n",
sc->sc_dev.dv_xname, rv);
@ -1601,7 +1603,7 @@ auich_powerhook(int why, void *addr)
return;
}
rv = pci_powerstate(sc->sc_pc, sc->sc_pt, &d0, &sc->sc_powerstate);
rv = pci_set_powerstate(sc->sc_pc, sc->sc_pt, sc->sc_powerstate);
if (rv)
aprint_error("%s: unable to set power state (err=%d)\n",
sc->sc_dev.dv_xname, rv);

View File

@ -1,4 +1,4 @@
/* $NetBSD: auixp.c,v 1.13 2006/05/14 21:45:00 elad Exp $ */
/* $NetBSD: auixp.c,v 1.14 2006/06/17 23:34:26 christos Exp $ */
/*
* Copyright (c) 2004, 2005 Reinoud Zandijk <reinoud@netbsd.org>
@ -50,7 +50,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: auixp.c,v 1.13 2006/05/14 21:45:00 elad Exp $");
__KERNEL_RCSID(0, "$NetBSD: auixp.c,v 1.14 2006/06/17 23:34:26 christos Exp $");
#include <sys/types.h>
#include <sys/errno.h>
@ -166,7 +166,6 @@ static paddr_t auixp_mappage(void *, void *, off_t, int);
/* power management (do we support that already?) */
static int auixp_power(struct auixp_softc *, int);
#if 0
static void auixp_powerhook(int, void *);
static int auixp_suspend(struct auixp_softc *);
@ -1103,7 +1102,7 @@ auixp_attach(struct device *parent, struct device *self, void *aux)
const char *intrstr;
uint32_t data;
char devinfo[256];
int revision, len;
int revision, len, error;
sc = (struct auixp_softc *)self;
pa = (struct pci_attach_args *)aux;
@ -1199,7 +1198,12 @@ auixp_attach(struct device *parent, struct device *self, void *aux)
aprint_normal("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
/* power up chip */
auixp_power(sc, PCI_PMCSR_STATE_D0);
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc,
pci_activate_null)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", sc->sc_dev.dv_xname,
error);
return;
}
/* init chip */
if (auixp_init(sc) == -1) {
@ -1776,26 +1780,6 @@ auixp_init(struct auixp_softc *sc)
*
*/
static int
auixp_power(struct auixp_softc *sc, int state)
{
pcitag_t tag;
pci_chipset_tag_t pc;
pcireg_t data;
int pmcapreg;
tag = sc->sc_tag;
pc = sc->sc_pct;
if (pci_get_capability(pc, tag, PCI_CAP_PWRMGMT, &pmcapreg, 0)) {
data = pci_conf_read(pc, tag, pmcapreg + PCI_PMCSR);
if ((data & PCI_PMCSR_STATE_MASK) != state)
pci_conf_write(pc, tag, pmcapreg + PCI_PMCSR, state);
}
return 0;
}
#if 0
static void
auixp_powerhook(int why, void *hdl)

View File

@ -1,4 +1,4 @@
/* $NetBSD: cs4280.c,v 1.38 2006/04/15 21:20:47 jmcneill Exp $ */
/* $NetBSD: cs4280.c,v 1.39 2006/06/17 23:34:26 christos Exp $ */
/*
* Copyright (c) 1999, 2000 Tatoku Ogaito. All rights reserved.
@ -52,7 +52,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cs4280.c,v 1.38 2006/04/15 21:20:47 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: cs4280.c,v 1.39 2006/06/17 23:34:26 christos Exp $");
#include "midi.h"
@ -238,7 +238,7 @@ cs4280_attach(struct device *parent, struct device *self, void *aux)
pcireg_t reg;
char devinfo[256];
uint32_t mem;
int pci_pwrmgmt_cap_reg, pci_pwrmgmt_csr_reg;
int error;
sc = (struct cs428x_softc *)self;
pa = (struct pci_attach_args *)aux;
@ -275,19 +275,12 @@ cs4280_attach(struct device *parent, struct device *self, void *aux)
sc->sc_dmatag = pa->pa_dmat;
/* Check and set Power State */
if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PWRMGMT,
&pci_pwrmgmt_cap_reg, 0)) {
pci_pwrmgmt_csr_reg = pci_pwrmgmt_cap_reg + PCI_PMCSR;
reg = pci_conf_read(pa->pa_pc, pa->pa_tag,
pci_pwrmgmt_csr_reg);
DPRINTF(("%s: Power State is %d\n",
sc->sc_dev.dv_xname, reg & PCI_PMCSR_STATE_MASK));
if ((reg & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_STATE_D0) {
pci_conf_write(pc, pa->pa_tag, pci_pwrmgmt_csr_reg,
(reg & ~PCI_PMCSR_STATE_MASK) |
PCI_PMCSR_STATE_D0);
}
/* power up chip */
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc,
pci_activate_null)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", sc->sc_dev.dv_xname,
error);
return;
}
/* Enable the device (set bus master flag) */

View File

@ -1,4 +1,4 @@
/* $NetBSD: cs4281.c,v 1.28 2006/04/15 21:20:47 jmcneill Exp $ */
/* $NetBSD: cs4281.c,v 1.29 2006/06/17 23:34:26 christos Exp $ */
/*
* Copyright (c) 2000 Tatoku Ogaito. All rights reserved.
@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cs4281.c,v 1.28 2006/04/15 21:20:47 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: cs4281.c,v 1.29 2006/06/17 23:34:26 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -188,7 +188,7 @@ cs4281_attach(struct device *parent, struct device *self, void *aux)
pci_intr_handle_t ih;
pcireg_t reg;
char devinfo[256];
int pci_pwrmgmt_cap_reg, pci_pwrmgmt_csr_reg;
int error;
sc = (struct cs428x_softc *)self;
pa = (struct pci_attach_args *)aux;
@ -215,23 +215,12 @@ cs4281_attach(struct device *parent, struct device *self, void *aux)
sc->sc_dmatag = pa->pa_dmat;
/*
* Set Power State D0.
* Without do this, 0xffffffff is read from all registers after
* using Windows.
* On my IBM Thinkpad X20, it is set to D3 after using Windows2000.
*/
if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PWRMGMT,
&pci_pwrmgmt_cap_reg, 0)) {
pci_pwrmgmt_csr_reg = pci_pwrmgmt_cap_reg + PCI_PMCSR;
reg = pci_conf_read(pa->pa_pc, pa->pa_tag,
pci_pwrmgmt_csr_reg);
if ((reg & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_STATE_D0) {
pci_conf_write(pc, pa->pa_tag, pci_pwrmgmt_csr_reg,
(reg & ~PCI_PMCSR_STATE_MASK) |
PCI_PMCSR_STATE_D0);
}
/* power up chip */
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc,
pci_activate_null)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", sc->sc_dev.dv_xname,
error);
return;
}
/* Enable the device (set bus master flag) */

View File

@ -1,4 +1,4 @@
/* $NetBSD: esa.c,v 1.31 2005/12/11 12:22:49 christos Exp $ */
/* $NetBSD: esa.c,v 1.32 2006/06/17 23:34:26 christos Exp $ */
/*
* Copyright (c) 2001, 2002 Jared D. McNeill <jmcneill@invisible.ca>
@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: esa.c,v 1.31 2005/12/11 12:22:49 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: esa.c,v 1.32 2006/06/17 23:34:26 christos Exp $");
#include <sys/types.h>
#include <sys/errno.h>
@ -161,7 +161,6 @@ static void esa_remove_list(struct esa_voice *, struct esa_list *,
int);
/* power management */
static int esa_power(struct esa_softc *, int);
static void esa_powerhook(int, void *);
static int esa_suspend(struct esa_softc *);
static int esa_resume(struct esa_softc *);
@ -1009,6 +1008,7 @@ esa_attach(struct device *parent, struct device *self, void *aux)
char devinfo[256];
int revision, len;
int i;
int error;
sc = (struct esa_softc *)self;
pa = (struct pci_attach_args *)aux;
@ -1063,8 +1063,13 @@ esa_attach(struct device *parent, struct device *self, void *aux)
}
aprint_normal("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
/* Power up chip */
esa_power(sc, PCI_PMCSR_STATE_D0);
/* power up chip */
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc,
pci_activate_null)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", sc->sc_dev.dv_xname,
error);
return;
}
/* Init chip */
if (esa_init(sc) == -1) {
@ -1629,25 +1634,6 @@ esa_remove_list(struct esa_voice *vc, struct esa_list *el, int index)
return;
}
static int
esa_power(struct esa_softc *sc, int state)
{
pcitag_t tag;
pci_chipset_tag_t pc;
pcireg_t data;
int pmcapreg;
tag = sc->sc_tag;
pc = sc->sc_pct;
if (pci_get_capability(pc, tag, PCI_CAP_PWRMGMT, &pmcapreg, 0)) {
data = pci_conf_read(pc, tag, pmcapreg + PCI_PMCSR);
if ((data & PCI_PMCSR_STATE_MASK) != state)
pci_conf_write(pc, tag, pmcapreg + PCI_PMCSR, state);
}
return 0;
}
static void
esa_powerhook(int why, void *hdl)
{
@ -1672,6 +1658,7 @@ esa_suspend(struct esa_softc *sc)
bus_space_tag_t iot;
bus_space_handle_t ioh;
int i, index;
int error;
iot = sc->sc_iot;
ioh = sc->sc_ioh;
@ -1692,7 +1679,9 @@ esa_suspend(struct esa_softc *sc)
sc->savemem[index++] = esa_read_assp(sc,
ESA_MEMTYPE_INTERNAL_DATA, i);
esa_power(sc, PCI_PMCSR_STATE_D3);
if ((error = pci_set_powerstate(sc->sc_pct, sc->sc_tag,
PCI_PMCSR_STATE_D3)))
return error;
return 0;
}
@ -1704,12 +1693,15 @@ esa_resume(struct esa_softc *sc)
bus_space_handle_t ioh;
int i, index;
uint8_t reset_state;
int error;
iot = sc->sc_iot;
ioh = sc->sc_ioh;
index = 0;
esa_power(sc, PCI_PMCSR_STATE_D0);
if ((error = pci_set_powerstate(sc->sc_pct, sc->sc_tag,
PCI_PMCSR_STATE_D0)))
return error;
delay(10000);
esa_config(sc);

View File

@ -1,4 +1,4 @@
/* $NetBSD: esm.c,v 1.34 2006/04/14 19:08:30 christos Exp $ */
/* $NetBSD: esm.c,v 1.35 2006/06/17 23:34:26 christos Exp $ */
/*-
* Copyright (c) 2002, 2003 Matt Fredette
@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: esm.c,v 1.34 2006/04/14 19:08:30 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: esm.c,v 1.35 2006/06/17 23:34:26 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -528,24 +528,6 @@ wc_wrchctl(struct esm_softc *ess, int ch, uint16_t data)
wc_wrreg(ess, ch << 3, data);
}
/* Power management */
void
esm_power(struct esm_softc *ess, int status)
{
pcireg_t data;
int pmcapreg;
if (pci_get_capability(ess->pc, ess->tag, PCI_CAP_PWRMGMT,
&pmcapreg, 0)) {
data = pci_conf_read(ess->pc, ess->tag, pmcapreg + PCI_PMCSR);
if ((data && PCI_PMCSR_STATE_MASK) != status)
pci_conf_write(ess->pc, ess->tag,
pmcapreg + PCI_PMCSR, status);
}
}
/* -----------------------------
* Controller.
*/
@ -1587,6 +1569,7 @@ esm_attach(struct device *parent, struct device *self, void *aux)
int revision;
uint16_t codec_data;
uint16_t pcmbar;
int error;
ess = (struct esm_softc *)self;
pa = (struct pci_attach_args *)aux;
@ -1645,8 +1628,13 @@ esm_attach(struct device *parent, struct device *self, void *aux)
* Setup PCI config registers
*/
/* set to power state D0 */
esm_power(ess, PCI_PMCSR_STATE_D0);
/* power up chip */
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, ess,
pci_activate_null)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", ess->sc_dev.dv_xname,
error);
return;
}
delay(100000);
/* Disable all legacy emulations. */
@ -1743,6 +1731,7 @@ int
esm_suspend(struct esm_softc *ess)
{
int x;
int error;
x = splaudio();
wp_stoptimer(ess);
@ -1757,7 +1746,8 @@ esm_suspend(struct esm_softc *ess)
delay(20);
bus_space_write_4(ess->st, ess->sh, PORT_RINGBUS_CTRL, 0);
delay(1);
esm_power(ess, PCI_PMCSR_STATE_D3);
if ((error = pci_set_powerstate(ess->pc, ess->tag, PCI_PMCSR_STATE_D3)))
return error;
return 0;
}
@ -1766,8 +1756,10 @@ int
esm_resume(struct esm_softc *ess)
{
int x;
int error;
esm_power(ess, PCI_PMCSR_STATE_D0);
if ((error = pci_set_powerstate(ess->pc, ess->tag, PCI_PMCSR_STATE_D0)))
return error;
delay(100000);
esm_init(ess);

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_atw_pci.c,v 1.11 2005/12/11 12:22:49 christos Exp $ */
/* $NetBSD: if_atw_pci.c,v 1.12 2006/06/17 23:34:26 christos Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2002 The NetBSD Foundation, Inc.
@ -44,7 +44,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_atw_pci.c,v 1.11 2005/12/11 12:22:49 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_atw_pci.c,v 1.12 2006/06/17 23:34:26 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -177,8 +177,7 @@ atw_pci_attach(struct device *parent, struct device *self, void *aux)
bus_space_handle_t ioh, memh;
int ioh_valid, memh_valid;
const struct atw_pci_product *app;
pcireg_t reg;
int pmreg;
int error;
psc->psc_pc = pa->pa_pc;
psc->psc_pcitag = pa->pa_tag;
@ -202,39 +201,12 @@ atw_pci_attach(struct device *parent, struct device *self, void *aux)
printf(": %s, revision %d.%d\n", app->app_product_name,
(sc->sc_rev >> 4) & 0xf, sc->sc_rev & 0xf);
/*
* Check to see if the device is in power-save mode, and
* being it out if necessary.
*
* XXX This code comes almost verbatim from if_tlp_pci.c. I do
* not understand it. Tulip clears the "sleep mode" bit in the
* CFDA register, first. There is an equivalent (?) register at the
* same place in the ADM8211, but the docs do not assign its bits
* any meanings. -dcy
*/
if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) {
reg = pci_conf_read(pc, pa->pa_tag, pmreg + PCI_PMCSR);
switch (reg & PCI_PMCSR_STATE_MASK) {
case PCI_PMCSR_STATE_D1:
case PCI_PMCSR_STATE_D2:
printf(": waking up from power state D%d\n%s",
reg & PCI_PMCSR_STATE_MASK, sc->sc_dev.dv_xname);
pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
(reg & ~PCI_PMCSR_STATE_MASK) |
PCI_PMCSR_STATE_D0);
break;
case PCI_PMCSR_STATE_D3:
/*
* The card has lost all configuration data in
* this state, so punt.
*/
printf(": unable to wake up from power state D3, "
"reboot required.\n");
pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
(reg & ~PCI_PMCSR_STATE_MASK) |
PCI_PMCSR_STATE_D0);
return;
}
/* power up chip */
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc,
NULL)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", sc->sc_dev.dv_xname,
error);
return;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_epic_pci.c,v 1.29 2005/12/11 12:22:49 christos Exp $ */
/* $NetBSD: if_epic_pci.c,v 1.30 2006/06/17 23:34:26 christos Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_epic_pci.c,v 1.29 2005/12/11 12:22:49 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_epic_pci.c,v 1.30 2006/06/17 23:34:26 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -169,8 +169,8 @@ epic_pci_attach(struct device *parent, struct device *self, void *aux)
const struct epic_pci_subsys_info *esp;
bus_space_tag_t iot, memt;
bus_space_handle_t ioh, memh;
pcireg_t reg;
int pmreg, ioh_valid, memh_valid;
int ioh_valid, memh_valid;
int error;
aprint_naive(": Ethernet controller\n");
@ -183,30 +183,12 @@ epic_pci_attach(struct device *parent, struct device *self, void *aux)
aprint_normal(": %s, rev. %d\n", epp->epp_name,
PCI_REVISION(pa->pa_class));
if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) {
reg = pci_conf_read(pc, pa->pa_tag, pmreg + PCI_PMCSR);
switch (reg & PCI_PMCSR_STATE_MASK) {
case PCI_PMCSR_STATE_D1:
case PCI_PMCSR_STATE_D2:
aprint_normal("%s: waking up from power state D%d\n",
sc->sc_dev.dv_xname, reg & PCI_PMCSR_STATE_MASK);
pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
(reg & ~PCI_PMCSR_STATE_MASK) |
PCI_PMCSR_STATE_D0);
break;
case PCI_PMCSR_STATE_D3:
/*
* IO and MEM are disabled. We can't enable
* the card because the BARs might be invalid.
*/
aprint_error(
"%s: unable to wake up from power state D3, "
"reboot required.\n", sc->sc_dev.dv_xname);
pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
(reg & ~PCI_PMCSR_STATE_MASK) |
PCI_PMCSR_STATE_D0);
return;
}
/* power up chip */
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc,
NULL)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", sc->sc_dev.dv_xname,
error);
return;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_ex_pci.c,v 1.40 2005/12/11 12:22:49 christos Exp $ */
/* $NetBSD: if_ex_pci.c,v 1.41 2006/06/17 23:34:26 christos Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_ex_pci.c,v 1.40 2005/12/11 12:22:49 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_ex_pci.c,v 1.41 2006/06/17 23:34:26 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -106,7 +106,7 @@ static int ex_pci_enable(struct ex_softc *);
static void ex_pci_disable(struct ex_softc *);
static void ex_pci_confreg_restore(struct ex_pci_softc *);
static void ex_d3tod0( struct ex_softc *, struct pci_attach_args *);
static int ex_d3tod0(pci_chipset_tag_t, pcitag_t, void *, pcireg_t);
CFATTACH_DECL(ex_pci, sizeof(struct ex_pci_softc),
ex_pci_match, ex_pci_attach, NULL, NULL);
@ -219,8 +219,8 @@ ex_pci_attach(struct device *parent, struct device *self, void *aux)
pci_intr_handle_t ih;
const struct ex_pci_product *epp;
const char *intrstr = NULL;
int rev, pmreg;
pcireg_t reg;
int rev;
int error;
aprint_naive(": Ethernet controller\n");
@ -276,35 +276,19 @@ ex_pci_attach(struct device *parent, struct device *self, void *aux)
psc->psc_regs[PCI_INTERRUPT_REG>>2] =
pci_conf_read(pc, pa->pa_tag, PCI_INTERRUPT_REG);
/* Get it out of power save mode if needed (BIOS bugs) */
if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) {
/* power up chip */
switch ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc, ex_d3tod0))) {
case EOPNOTSUPP:
break;
case 0:
sc->enable = ex_pci_enable;
sc->disable = ex_pci_disable;
psc->psc_pwrmgmt_csr_reg = pmreg + PCI_PMCSR;
reg = pci_conf_read(pc, pa->pa_tag, psc->psc_pwrmgmt_csr_reg);
psc->psc_pwrmgmt_csr = (reg & ~PCI_PMCSR_STATE_MASK) |
PCI_PMCSR_STATE_D0;
switch (reg & PCI_PMCSR_STATE_MASK) {
case PCI_PMCSR_STATE_D3:
aprint_normal("%s: found in power state D3, "
"attempting to recover.\n", sc->sc_dev.dv_xname);
ex_d3tod0(sc, pa);
aprint_normal("%s: changed power state to D0.\n",
sc->sc_dev.dv_xname);
break;
case PCI_PMCSR_STATE_D1:
case PCI_PMCSR_STATE_D2:
aprint_normal("%s: waking up from power state D%d\n",
sc->sc_dev.dv_xname, reg);
pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
(reg & ~PCI_PMCSR_STATE_MASK) | PCI_PMCSR_STATE_D0);
break;
}
break;
default:
aprint_error("%s: cannot activate %d\n", sc->sc_dev.dv_xname,
error);
return;
}
sc->enabled = 1;
/* Map and establish the interrupt. */
@ -345,8 +329,8 @@ ex_pci_intr_ack(struct ex_softc *sc)
PCI_INTRACK);
}
static void
ex_d3tod0(struct ex_softc *sc, struct pci_attach_args *pa)
static int
ex_d3tod0(pci_chipset_tag_t pc, pcitag_t tag, void *ssc, pcireg_t state)
{
#define PCI_CACHE_LAT_BIST 0x0c
@ -359,30 +343,37 @@ ex_d3tod0(struct ex_softc *sc, struct pci_attach_args *pa)
#define PCI_EXP_ROM_BAR 0x30
#define PCI_INT_GNT_LAT 0x3c
pci_chipset_tag_t pc = pa->pa_pc;
u_int32_t base0;
u_int32_t base1;
u_int32_t romaddr;
u_int32_t pci_command;
u_int32_t pci_int_lat;
u_int32_t pci_cache_lat;
struct ex_softc *sc = ssc;
pci_command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
base0 = pci_conf_read(pc, pa->pa_tag, PCI_BAR0);
base1 = pci_conf_read(pc, pa->pa_tag, PCI_BAR1);
romaddr = pci_conf_read(pc, pa->pa_tag, PCI_EXP_ROM_BAR);
pci_cache_lat= pci_conf_read(pc, pa->pa_tag, PCI_CACHE_LAT_BIST);
pci_int_lat = pci_conf_read(pc, pa->pa_tag, PCI_INT_GNT_LAT);
if (state != PCI_PMCSR_STATE_D3)
return 0;
pci_conf_write(pc, pa->pa_tag, PCI_POWERCTL, 0);
pci_conf_write(pc, pa->pa_tag, PCI_BAR0, base0);
pci_conf_write(pc, pa->pa_tag, PCI_BAR1, base1);
pci_conf_write(pc, pa->pa_tag, PCI_EXP_ROM_BAR, romaddr);
pci_conf_write(pc, pa->pa_tag, PCI_INT_GNT_LAT, pci_int_lat);
pci_conf_write(pc, pa->pa_tag, PCI_CACHE_LAT_BIST, pci_cache_lat);
pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
aprint_normal("%s: found in power state D%d, "
"attempting to recover.\n", sc->sc_dev.dv_xname, state);
pci_command = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
base0 = pci_conf_read(pc, tag, PCI_BAR0);
base1 = pci_conf_read(pc, tag, PCI_BAR1);
romaddr = pci_conf_read(pc, tag, PCI_EXP_ROM_BAR);
pci_cache_lat= pci_conf_read(pc, tag, PCI_CACHE_LAT_BIST);
pci_int_lat = pci_conf_read(pc, tag, PCI_INT_GNT_LAT);
pci_conf_write(pc, tag, PCI_POWERCTL, 0);
pci_conf_write(pc, tag, PCI_BAR0, base0);
pci_conf_write(pc, tag, PCI_BAR1, base1);
pci_conf_write(pc, tag, PCI_EXP_ROM_BAR, romaddr);
pci_conf_write(pc, tag, PCI_INT_GNT_LAT, pci_int_lat);
pci_conf_write(pc, tag, PCI_CACHE_LAT_BIST, pci_cache_lat);
pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG,
(PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_IO_ENABLE));
aprint_normal("%s: changed power state to D0.\n",
sc->sc_dev.dv_xname);
return 0;
}
static void

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_fxp_pci.c,v 1.44 2006/01/10 20:31:36 christos Exp $ */
/* $NetBSD: if_fxp_pci.c,v 1.45 2006/06/17 23:34:27 christos Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_fxp_pci.c,v 1.44 2006/01/10 20:31:36 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_fxp_pci.c,v 1.45 2006/06/17 23:34:27 christos Exp $");
#include "rnd.h"
@ -263,7 +263,7 @@ fxp_pci_attach(struct device *parent, struct device *self, void *aux)
bus_addr_t addr;
bus_size_t size;
int flags;
int pci_pwrmgmt_cap_reg;
int error;
aprint_naive(": Ethernet controller\n");
@ -447,27 +447,21 @@ fxp_pci_attach(struct device *parent, struct device *self, void *aux)
psc->psc_regs[(PCI_MAPREG_START+0x8)>>2] =
pci_conf_read(pc, pa->pa_tag, PCI_MAPREG_START+0x8);
/*
* Work around BIOS ACPI bugs where the chip is inadvertantly
* left in ACPI D3 (lowest power state). First confirm the device
* supports ACPI power management, then move it to the D0 (fully
* functional) state if it is not already there.
*/
if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT,
&pci_pwrmgmt_cap_reg, 0)) {
pcireg_t reg;
/* power up chip */
switch ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc,
pci_activate_null))) {
case EOPNOTSUPP:
break;
case 0:
sc->sc_enable = fxp_pci_enable;
sc->sc_disable = fxp_pci_disable;
psc->psc_pwrmgmt_csr_reg = pci_pwrmgmt_cap_reg + PCI_PMCSR;
reg = pci_conf_read(pc, pa->pa_tag, psc->psc_pwrmgmt_csr_reg);
psc->psc_pwrmgmt_csr = (reg & ~PCI_PMCSR_STATE_MASK) |
PCI_PMCSR_STATE_D0;
if ((reg & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_STATE_D0)
pci_conf_write(pc, pa->pa_tag, psc->psc_pwrmgmt_csr_reg,
psc->psc_pwrmgmt_csr);
break;
default:
aprint_error("%s: cannot activate %d\n", sc->sc_dev.dv_xname,
error);
return;
}
/* Restore PCI configuration registers. */
fxp_pci_confreg_restore(psc);

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_iwi.c,v 1.49 2006/05/28 13:12:42 blymn Exp $ */
/* $NetBSD: if_iwi.c,v 1.50 2006/06/17 23:34:27 christos Exp $ */
/*-
* Copyright (c) 2004, 2005
@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_iwi.c,v 1.49 2006/05/28 13:12:42 blymn Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_iwi.c,v 1.50 2006/06/17 23:34:27 christos Exp $");
/*-
* Intel(R) PRO/Wireless 2200BG/2225BG/2915ABG driver
@ -250,6 +250,14 @@ iwi_attach(struct device *parent, struct device *self, void *aux)
/* clear unit numbers allocated to IBSS */
sc->sc_unr = 0;
/* power up chip */
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc,
NULL)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", sc->sc_dev.dv_xname,
error);
return;
}
/* enable bus-mastering */
data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
data |= PCI_COMMAND_MASTER_ENABLE;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_pcn.c,v 1.30 2006/06/14 13:30:35 tsutsui Exp $ */
/* $NetBSD: if_pcn.c,v 1.31 2006/06/17 23:34:27 christos Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@ -67,7 +67,7 @@
#include "opt_pcn.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_pcn.c,v 1.30 2006/06/14 13:30:35 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_pcn.c,v 1.31 2006/06/17 23:34:27 christos Exp $");
#include "bpfilter.h"
#include "rnd.h"
@ -568,10 +568,8 @@ pcn_attach(struct device *parent, struct device *self, void *aux)
bus_dma_segment_t seg;
int ioh_valid, memh_valid;
int i, rseg, error;
pcireg_t pmode;
uint32_t chipid, reg;
uint8_t enaddr[ETHER_ADDR_LEN];
int pmreg;
callout_init(&sc->sc_tick_ch);
@ -605,25 +603,12 @@ pcn_attach(struct device *parent, struct device *self, void *aux)
pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
PCI_COMMAND_MASTER_ENABLE);
/* Get it out of power save mode, if needed. */
if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) {
pmode = pci_conf_read(pc, pa->pa_tag, pmreg + PCI_PMCSR) &
PCI_PMCSR_STATE_MASK;
if (pmode == PCI_PMCSR_STATE_D3) {
/*
* The card has lost all configuration data in
* this state, so punt.
*/
printf("%s: unable to wake from power state D3\n",
sc->sc_dev.dv_xname);
return;
}
if (pmode != PCI_PMCSR_STATE_D0) {
printf("%s: waking up from power date D%d\n",
sc->sc_dev.dv_xname, pmode);
pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
PCI_PMCSR_STATE_D0);
}
/* power up chip */
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc,
NULL)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", sc->sc_dev.dv_xname,
error);
return;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_rtw_pci.c,v 1.5 2006/04/28 13:43:15 rpaulo Exp $ */
/* $NetBSD: if_rtw_pci.c,v 1.6 2006/06/17 23:34:27 christos Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2002 The NetBSD Foundation, Inc.
@ -46,7 +46,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_rtw_pci.c,v 1.5 2006/04/28 13:43:15 rpaulo Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_rtw_pci.c,v 1.6 2006/06/17 23:34:27 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -182,7 +182,7 @@ rtw_pci_attach(struct device *parent, struct device *self, void *aux)
int ioh_valid, memh_valid;
const struct rtw_pci_product *app;
pcireg_t reg;
int pmreg;
int error;
psc->psc_pc = pa->pa_pc;
psc->psc_pcitag = pa->pa_tag;
@ -206,39 +206,12 @@ rtw_pci_attach(struct device *parent, struct device *self, void *aux)
aprint_normal(": %s, revision %d.%d\n", app->app_product_name,
(sc->sc_rev >> 4) & 0xf, sc->sc_rev & 0xf);
/*
* Check to see if the device is in power-save mode, and
* being it out if necessary.
*
* XXX This code comes almost verbatim from if_tlp_pci.c. I do
* not understand it. Tulip clears the "sleep mode" bit in the
* CFDA register, first. There is an equivalent (?) register at the
* same place in the ADM8211, but the docs do not assign its bits
* any meanings. -dcy
*/
if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) {
reg = pci_conf_read(pc, pa->pa_tag, pmreg + PCI_PMCSR);
switch (reg & PCI_PMCSR_STATE_MASK) {
case PCI_PMCSR_STATE_D1:
case PCI_PMCSR_STATE_D2:
aprint_normal(": waking up from power state D%d\n%s",
reg & PCI_PMCSR_STATE_MASK, sc->sc_dev.dv_xname);
pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
(reg & ~PCI_PMCSR_STATE_MASK) |
PCI_PMCSR_STATE_D0);
break;
case PCI_PMCSR_STATE_D3:
/*
* The card has lost all configuration data in
* this state, so punt.
*/
aprint_normal(": unable to wake up from power state"
" D3, reboot required.\n");
pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
(reg & ~PCI_PMCSR_STATE_MASK) |
PCI_PMCSR_STATE_D0);
return;
}
/* power up chip */
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc,
NULL)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", sc->sc_dev.dv_xname,
error);
return;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_sf_pci.c,v 1.9 2005/12/11 12:22:49 christos Exp $ */
/* $NetBSD: if_sf_pci.c,v 1.10 2006/06/17 23:34:27 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_sf_pci.c,v 1.9 2005/12/11 12:22:49 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_sf_pci.c,v 1.10 2006/06/17 23:34:27 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -182,7 +182,7 @@ sf_pci_attach(struct device *parent, struct device *self, void *aux)
bus_space_tag_t iot, memt;
bus_space_handle_t ioh, memh;
pcireg_t reg;
int pmreg, ioh_valid, memh_valid;
int error, ioh_valid, memh_valid;
spp = sf_pci_lookup(pa);
if (spp == NULL) {
@ -192,27 +192,12 @@ sf_pci_attach(struct device *parent, struct device *self, void *aux)
printf(": %s, rev. %d\n", spp->spp_name, PCI_REVISION(pa->pa_class));
if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PWRMGMT,
&pmreg, 0)) {
reg = pci_conf_read(pa->pa_pc, pa->pa_tag, pmreg + PCI_PMCSR);
switch (reg & PCI_PMCSR_STATE_MASK) {
case PCI_PMCSR_STATE_D1:
case PCI_PMCSR_STATE_D2:
printf(": waking up from power state D%d\n%s",
reg & PCI_PMCSR_STATE_MASK, sc->sc_dev.dv_xname);
pci_conf_write(pa->pa_pc, pa->pa_tag, pmreg + PCI_PMCSR,
(reg & ~PCI_PMCSR_STATE_MASK) |
PCI_PMCSR_STATE_D0);
break;
case PCI_PMCSR_STATE_D3:
printf("%s: unable to wake up from power state D3\n",
sc->sc_dev.dv_xname);
pci_conf_write(pa->pa_pc, pa->pa_tag, pmreg + PCI_PMCSR,
(reg & ~PCI_PMCSR_STATE_MASK) |
PCI_PMCSR_STATE_D0);
return;
}
/* power up chip */
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc,
NULL)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", sc->sc_dev.dv_xname,
error);
return;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_sip.c,v 1.107 2006/04/18 13:07:03 pavel Exp $ */
/* $NetBSD: if_sip.c,v 1.108 2006/06/17 23:34:27 christos Exp $ */
/*-
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_sip.c,v 1.107 2006/04/18 13:07:03 pavel Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_sip.c,v 1.108 2006/06/17 23:34:27 christos Exp $");
#include "bpfilter.h"
#include "rnd.h"
@ -662,9 +662,8 @@ SIP_DECL(attach)(struct device *parent, struct device *self, void *aux)
int ioh_valid, memh_valid;
int i, rseg, error;
const struct sip_product *sip;
pcireg_t pmode;
u_int8_t enaddr[ETHER_ADDR_LEN];
int pmreg;
pcireg_t pmreg;
#ifdef DP83820
pcireg_t memtype;
u_int32_t reg;
@ -741,25 +740,12 @@ SIP_DECL(attach)(struct device *parent, struct device *self, void *aux)
pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
pmreg | PCI_COMMAND_MASTER_ENABLE);
/* Get it out of power save mode if needed. */
if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) {
pmode = pci_conf_read(pc, pa->pa_tag, pmreg + PCI_PMCSR) &
PCI_PMCSR_STATE_MASK;
if (pmode == PCI_PMCSR_STATE_D3) {
/*
* The card has lost all configuration data in
* this state, so punt.
*/
printf("%s: unable to wake up from power state D3\n",
sc->sc_dev.dv_xname);
return;
}
if (pmode != PCI_PMCSR_STATE_D0) {
printf("%s: waking up from power state D%d\n",
sc->sc_dev.dv_xname, pmode);
pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
PCI_PMCSR_STATE_D0);
}
/* power up chip */
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc,
NULL)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", sc->sc_dev.dv_xname,
error);
return;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_ste.c,v 1.22 2005/12/11 12:22:49 christos Exp $ */
/* $NetBSD: if_ste.c,v 1.23 2006/06/17 23:34:27 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_ste.c,v 1.22 2005/12/11 12:22:49 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_ste.c,v 1.23 2006/06/17 23:34:27 christos Exp $");
#include "bpfilter.h"
@ -315,10 +315,8 @@ ste_attach(struct device *parent, struct device *self, void *aux)
int ioh_valid, memh_valid;
int i, rseg, error;
const struct ste_product *sp;
pcireg_t pmode;
uint8_t enaddr[ETHER_ADDR_LEN];
uint16_t myea[ETHER_ADDR_LEN / 2];
int pmreg;
callout_init(&sc->sc_tick_ch);
@ -359,25 +357,12 @@ ste_attach(struct device *parent, struct device *self, void *aux)
pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
PCI_COMMAND_MASTER_ENABLE);
/* Get it out of power save mode if needed. */
if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) {
pmode = pci_conf_read(pc, pa->pa_tag, pmreg + PCI_PMCSR) &
PCI_PMCSR_STATE_MASK;
if (pmode == PCI_PMCSR_STATE_D3) {
/*
* The card has lost all configuration data in
* this state, so punt.
*/
printf("%s: unable to wake up from power state D3\n",
sc->sc_dev.dv_xname);
return;
}
if (pmode != PCI_PMCSR_STATE_D0) {
printf("%s: waking up from power state D%d\n",
sc->sc_dev.dv_xname, pmode);
pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
PCI_PMCSR_STATE_D0);
}
/* power up chip */
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc,
NULL)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", sc->sc_dev.dv_xname,
error);
return;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_stge.c,v 1.32 2005/12/11 12:22:49 christos Exp $ */
/* $NetBSD: if_stge.c,v 1.33 2006/06/17 23:34:27 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_stge.c,v 1.32 2005/12/11 12:22:49 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_stge.c,v 1.33 2006/06/17 23:34:27 christos Exp $");
#include "bpfilter.h"
@ -398,9 +398,7 @@ stge_attach(struct device *parent, struct device *self, void *aux)
int ioh_valid, memh_valid;
int i, rseg, error;
const struct stge_product *sp;
pcireg_t pmode;
uint8_t enaddr[ETHER_ADDR_LEN];
int pmreg;
callout_init(&sc->sc_tick_ch);
@ -443,27 +441,13 @@ stge_attach(struct device *parent, struct device *self, void *aux)
pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
PCI_COMMAND_MASTER_ENABLE);
/* Get it out of power save mode if needed. */
if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) {
pmode = pci_conf_read(pc, pa->pa_tag, pmreg + PCI_PMCSR) &
PCI_PMCSR_STATE_MASK;
if (pmode == PCI_PMCSR_STATE_D3) {
/*
* The card has lost all configuration data in
* this state, so punt.
*/
printf("%s: unable to wake up from power state D3\n",
sc->sc_dev.dv_xname);
return;
}
if (pmode != 0) {
printf("%s: waking up from power state D%d\n",
sc->sc_dev.dv_xname, pmode);
pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
PCI_PMCSR_STATE_D0);
}
/* power up chip */
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc,
NULL)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", sc->sc_dev.dv_xname,
error);
return;
}
/*
* Map and establish our interrupt.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_tlp_pci.c,v 1.91 2006/05/20 14:23:07 rpaulo Exp $ */
/* $NetBSD: if_tlp_pci.c,v 1.92 2006/06/17 23:34:27 christos Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2002 The NetBSD Foundation, Inc.
@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_tlp_pci.c,v 1.91 2006/05/20 14:23:07 rpaulo Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_tlp_pci.c,v 1.92 2006/06/17 23:34:27 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -350,7 +350,7 @@ tlp_pci_attach(struct device *parent, struct device *self, void *aux)
u_int8_t enaddr[ETHER_ADDR_LEN];
u_int32_t val = 0;
pcireg_t reg;
int pmreg;
int error;
sc->sc_devno = pa->pa_device;
psc->sc_pc = pa->pa_pc;
@ -511,30 +511,12 @@ tlp_pci_attach(struct device *parent, struct device *self, void *aux)
break;
}
if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) {
reg = pci_conf_read(pc, pa->pa_tag, pmreg + PCI_PMCSR);
switch (reg & PCI_PMCSR_STATE_MASK) {
case PCI_PMCSR_STATE_D1:
case PCI_PMCSR_STATE_D2:
printf("%s: waking up from power state D%d\n%s",
sc->sc_dev.dv_xname,
reg & PCI_PMCSR_STATE_MASK, sc->sc_dev.dv_xname);
pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
(reg & ~PCI_PMCSR_STATE_MASK) |
PCI_PMCSR_STATE_D0);
break;
case PCI_PMCSR_STATE_D3:
/*
* The card has lost all configuration data in
* this state, so punt.
*/
printf("%s: unable to wake up from power state D3, "
"reboot required.\n", sc->sc_dev.dv_xname);
pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
(reg & ~PCI_PMCSR_STATE_MASK) |
PCI_PMCSR_STATE_D0);
return;
}
/* power up chip */
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc,
NULL)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", sc->sc_dev.dv_xname,
error);
return;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_vr.c,v 1.75 2005/12/11 12:22:50 christos Exp $ */
/* $NetBSD: if_vr.c,v 1.76 2006/06/17 23:34:27 christos Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@ -104,7 +104,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_vr.c,v 1.75 2005/12/11 12:22:50 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_vr.c,v 1.76 2006/06/17 23:34:27 christos Exp $");
#include "rnd.h"
@ -217,6 +217,7 @@ struct vr_softc {
bus_space_handle_t vr_bsh; /* bus space handle */
bus_dma_tag_t vr_dmat; /* bus DMA tag */
pci_chipset_tag_t vr_pc; /* PCI chipset info */
pcitag_t vr_tag; /* PCI tag */
struct ethercom vr_ec; /* Ethernet common info */
u_int8_t vr_enaddr[ETHER_ADDR_LEN];
struct mii_data vr_mii; /* MII/media info */
@ -245,6 +246,10 @@ struct vr_softc {
int vr_rxptr; /* next ready RX descriptor */
u_int32_t vr_save_iobase;
u_int32_t vr_save_membase;
u_int32_t vr_save_irq;
#if NRND > 0
rndsource_element_t rnd_source; /* random source */
#endif
@ -326,6 +331,7 @@ static void vr_mii_statchg(struct device *);
static void vr_setmulti(struct vr_softc *);
static void vr_reset(struct vr_softc *);
static int vr_restore_state(pci_chipset_tag_t, pcitag_t, void *, pcireg_t);
int vr_copy_small = 0;
@ -1446,14 +1452,16 @@ vr_attach(struct device *parent, struct device *self, void *aux)
struct pci_attach_args *pa = (struct pci_attach_args *) aux;
bus_dma_segment_t seg;
struct vr_type *vrt;
u_int32_t pmreg, reg;
u_int32_t reg;
struct ifnet *ifp;
u_char eaddr[ETHER_ADDR_LEN];
int i, rseg, error;
#define PCI_CONF_WRITE(r, v) pci_conf_write(pa->pa_pc, pa->pa_tag, (r), (v))
#define PCI_CONF_READ(r) pci_conf_read(pa->pa_pc, pa->pa_tag, (r))
#define PCI_CONF_WRITE(r, v) pci_conf_write(sc->vr_pc, sc->vr_tag, (r), (v))
#define PCI_CONF_READ(r) pci_conf_read(sc->vr_pc, sc->vr_tag, (r))
sc->vr_pc = pa->pa_pc;
sc->vr_tag = pa->pa_tag;
callout_init(&sc->vr_tick_ch);
vrt = vr_lookup(pa);
@ -1468,30 +1476,16 @@ vr_attach(struct device *parent, struct device *self, void *aux)
* Handle power management nonsense.
*/
if (pci_get_capability(pa->pa_pc, pa->pa_tag,
PCI_CAP_PWRMGMT, &pmreg, 0)) {
reg = PCI_CONF_READ(pmreg + PCI_PMCSR);
if ((reg & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_STATE_D0) {
u_int32_t iobase, membase, irq;
sc->vr_save_iobase = PCI_CONF_READ(VR_PCI_LOIO);
sc->vr_save_membase = PCI_CONF_READ(VR_PCI_LOMEM);
sc->vr_save_irq = PCI_CONF_READ(PCI_INTERRUPT_REG);
/* Save important PCI config data. */
iobase = PCI_CONF_READ(VR_PCI_LOIO);
membase = PCI_CONF_READ(VR_PCI_LOMEM);
irq = PCI_CONF_READ(PCI_INTERRUPT_REG);
/* Reset the power state. */
printf("%s: chip is in D%d power mode "
"-- setting to D0\n",
sc->vr_dev.dv_xname, reg & PCI_PMCSR_STATE_MASK);
reg = (reg & ~PCI_PMCSR_STATE_MASK) |
PCI_PMCSR_STATE_D0;
PCI_CONF_WRITE(pmreg + PCI_PMCSR, reg);
/* Restore PCI config data. */
PCI_CONF_WRITE(VR_PCI_LOIO, iobase);
PCI_CONF_WRITE(VR_PCI_LOMEM, membase);
PCI_CONF_WRITE(PCI_INTERRUPT_REG, irq);
}
/* power up chip */
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc,
vr_restore_state)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", sc->vr_dev.dv_xname,
error);
return;
}
/* Make sure bus mastering is enabled. */
@ -1739,3 +1733,21 @@ vr_attach(struct device *parent, struct device *self, void *aux)
fail_0:
return;
}
static int
vr_restore_state(pci_chipset_tag_t pc, pcitag_t tag, void *ssc, pcireg_t state)
{
struct vr_softc *sc = ssc;
int error;
if (state == PCI_PMCSR_STATE_D0)
return 0;
if ((error = pci_set_powerstate(pc, tag, PCI_PMCSR_STATE_D0)))
return error;
/* Restore PCI config data. */
PCI_CONF_WRITE(VR_PCI_LOIO, sc->vr_save_iobase);
PCI_CONF_WRITE(VR_PCI_LOMEM, sc->vr_save_membase);
PCI_CONF_WRITE(PCI_INTERRUPT_REG, sc->vr_save_irq);
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_wm.c,v 1.121 2006/06/16 15:51:04 msaitoh Exp $ */
/* $NetBSD: if_wm.c,v 1.122 2006/06/17 23:34:27 christos Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@ -47,7 +47,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.121 2006/06/16 15:51:04 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.122 2006/06/17 23:34:27 christos Exp $");
#include "bpfilter.h"
#include "rnd.h"
@ -788,7 +788,6 @@ wm_attach(struct device *parent, struct device *self, void *aux)
uint16_t myea[ETHER_ADDR_LEN / 2], cfg1, cfg2, swdpin;
pcireg_t preg, memtype;
uint32_t reg;
int pmreg;
callout_init(&sc->sc_tick_ch);
@ -887,25 +886,12 @@ wm_attach(struct device *parent, struct device *self, void *aux)
preg &= ~PCI_COMMAND_INVALIDATE_ENABLE;
pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, preg);
/* Get it out of power save mode, if needed. */
if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) {
preg = pci_conf_read(pc, pa->pa_tag, pmreg + PCI_PMCSR) &
PCI_PMCSR_STATE_MASK;
if (preg == PCI_PMCSR_STATE_D3) {
/*
* The card has lost all configuration data in
* this state, so punt.
*/
aprint_error("%s: unable to wake from power state D3\n",
sc->sc_dev.dv_xname);
return;
}
if (preg != PCI_PMCSR_STATE_D0) {
aprint_normal("%s: waking up from power state D%d\n",
sc->sc_dev.dv_xname, preg);
pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
PCI_PMCSR_STATE_D0);
}
/* power up chip */
if ((error = pci_activate(pa->pa_pc, pa->pa_tag, sc,
NULL)) && error != EOPNOTSUPP) {
aprint_error("%s: cannot activate %d\n", sc->sc_dev.dv_xname,
error);
return;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: pci.c,v 1.98 2006/03/29 06:00:46 thorpej Exp $ */
/* $NetBSD: pci.c,v 1.99 2006/06/17 23:34:27 christos Exp $ */
/*
* Copyright (c) 1995, 1996, 1997, 1998
@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.98 2006/03/29 06:00:46 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.99 2006/06/17 23:34:27 christos Exp $");
#include "opt_pci.h"
@ -500,81 +500,6 @@ pci_enumerate_bus(struct pci_softc *sc, const int *locators,
}
#endif /* PCI_MACHDEP_ENUMERATE_BUS */
/*
* Power Management Capability (Rev 2.2)
*/
int
pci_powerstate(pci_chipset_tag_t pc, pcitag_t tag, const int *newstate,
int *oldstate)
{
int offset;
pcireg_t value, cap, now;
if (!pci_get_capability(pc, tag, PCI_CAP_PWRMGMT, &offset, &value))
return EOPNOTSUPP;
cap = value >> 16;
value = pci_conf_read(pc, tag, offset + PCI_PMCSR);
now = value & PCI_PMCSR_STATE_MASK;
value &= ~PCI_PMCSR_STATE_MASK;
if (oldstate) {
switch (now) {
case PCI_PMCSR_STATE_D0:
*oldstate = PCI_PWR_D0;
break;
case PCI_PMCSR_STATE_D1:
*oldstate = PCI_PWR_D1;
break;
case PCI_PMCSR_STATE_D2:
*oldstate = PCI_PWR_D2;
break;
case PCI_PMCSR_STATE_D3:
*oldstate = PCI_PWR_D3;
break;
default:
return EINVAL;
}
}
if (newstate == NULL)
return 0;
switch (*newstate) {
case PCI_PWR_D0:
if (now == PCI_PMCSR_STATE_D0)
return 0;
value |= PCI_PMCSR_STATE_D0;
break;
case PCI_PWR_D1:
if (now == PCI_PMCSR_STATE_D1)
return 0;
if (now == PCI_PMCSR_STATE_D2 || now == PCI_PMCSR_STATE_D3)
return EINVAL;
if (!(cap & PCI_PMCR_D1SUPP))
return EOPNOTSUPP;
value |= PCI_PMCSR_STATE_D1;
break;
case PCI_PWR_D2:
if (now == PCI_PMCSR_STATE_D2)
return 0;
if (now == PCI_PMCSR_STATE_D3)
return EINVAL;
if (!(cap & PCI_PMCR_D2SUPP))
return EOPNOTSUPP;
value |= PCI_PMCSR_STATE_D2;
break;
case PCI_PWR_D3:
if (now == PCI_PMCSR_STATE_D3)
return 0;
value |= PCI_PMCSR_STATE_D3;
break;
default:
return EINVAL;
}
pci_conf_write(pc, tag, offset + PCI_PMCSR, value);
DELAY(1000);
return 0;
}
/*
* Vital Product Data (PCI 2.2)
@ -688,5 +613,125 @@ pci_conf_restore(pci_chipset_tag_t pc, pcitag_t tag,
return;
}
/*
* Power Management Capability (Rev 2.2)
*/
int
pci_get_powerstate(pci_chipset_tag_t pc, pcitag_t tag , pcireg_t *state)
{
int offset;
pcireg_t value, cap, now;
if (!pci_get_capability(pc, tag, PCI_CAP_PWRMGMT, &offset, &value))
return EOPNOTSUPP;
cap = value >> PCI_PMCR_SHIFT;
value = pci_conf_read(pc, tag, offset + PCI_PMCSR);
now = value & PCI_PMCSR_STATE_MASK;
switch (now) {
case PCI_PMCSR_STATE_D0:
case PCI_PMCSR_STATE_D1:
case PCI_PMCSR_STATE_D2:
case PCI_PMCSR_STATE_D3:
*state = now;
return 0;
default:
return EINVAL;
}
}
int
pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag, pcireg_t state)
{
int offset;
pcireg_t value, cap, now;
if (!pci_get_capability(pc, tag, PCI_CAP_PWRMGMT, &offset, &value))
return EOPNOTSUPP;
cap = value >> PCI_PMCR_SHIFT;
value = pci_conf_read(pc, tag, offset + PCI_PMCSR);
now = value & PCI_PMCSR_STATE_MASK;
value &= ~PCI_PMCSR_STATE_MASK;
if (now == state)
return 0;
switch (state) {
case PCI_PMCSR_STATE_D0:
value |= PCI_PMCSR_STATE_D0;
break;
case PCI_PMCSR_STATE_D1:
if (now == PCI_PMCSR_STATE_D2 || now == PCI_PMCSR_STATE_D3)
return EINVAL;
if (!(cap & PCI_PMCR_D1SUPP))
return EOPNOTSUPP;
value |= PCI_PMCSR_STATE_D1;
break;
case PCI_PMCSR_STATE_D2:
if (now == PCI_PMCSR_STATE_D3)
return EINVAL;
if (!(cap & PCI_PMCR_D2SUPP))
return EOPNOTSUPP;
value |= PCI_PMCSR_STATE_D2;
break;
case PCI_PMCSR_STATE_D3:
if (now == PCI_PMCSR_STATE_D3)
return 0;
value |= PCI_PMCSR_STATE_D3;
break;
default:
return EINVAL;
}
pci_conf_write(pc, tag, offset + PCI_PMCSR, value);
DELAY(1000);
return 0;
}
int
pci_activate(pci_chipset_tag_t pc, pcitag_t tag, void *sc,
int (*wakefun)(pci_chipset_tag_t, pcitag_t, void *, pcireg_t))
{
struct device *dv = sc;
pcireg_t pmode;
int error;
if ((error = pci_get_powerstate(pc, tag, &pmode)))
return error;
switch (pmode) {
case PCI_PMCSR_STATE_D0:
break;
case PCI_PMCSR_STATE_D3:
if (wakefun == NULL) {
/*
* The card has lost all configuration data in
* this state, so punt.
*/
aprint_error(
"%s: unable to wake up from power state D3\n",
dv->dv_xname);
return EOPNOTSUPP;
}
/*FALLTHROUGH*/
default:
if (wakefun) {
error = (*wakefun)(pc, tag, sc, pmode);
if (error)
return error;
}
aprint_normal("%s: waking up from power state D%d\n",
dv->dv_xname, pmode);
if ((error = pci_set_powerstate(pc, tag, PCI_PMCSR_STATE_D0)))
return error;
}
return 0;
}
int
pci_activate_null(pci_chipset_tag_t pc, pcitag_t tag, void *sc, pcireg_t state)
{
return 0;
}
CFATTACH_DECL2(pci, sizeof(struct pci_softc),
pcimatch, pciattach, NULL, NULL, pcirescan, pcidevdetached);

View File

@ -1,4 +1,4 @@
/* $NetBSD: pcireg.h,v 1.50 2006/05/31 10:01:18 drochner Exp $ */
/* $NetBSD: pcireg.h,v 1.51 2006/06/17 23:34:27 christos Exp $ */
/*
* Copyright (c) 1995, 1996, 1999, 2000
@ -451,6 +451,7 @@ typedef u_int8_t pci_revision_t;
*/
/* Power Management Capability Register */
#define PCI_PMCR_SHIFT 16
#define PCI_PMCR 0x02
#define PCI_PMCR_D1SUPP 0x0200
#define PCI_PMCR_D2SUPP 0x0400

View File

@ -1,4 +1,4 @@
/* $NetBSD: pcivar.h,v 1.71 2006/03/01 18:53:40 gdamore Exp $ */
/* $NetBSD: pcivar.h,v 1.72 2006/06/17 23:34:27 christos Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@ -240,6 +240,11 @@ int pci_find_device(struct pci_attach_args *pa,
int pci_dma64_available(struct pci_attach_args *);
void pci_conf_capture(pci_chipset_tag_t, pcitag_t, struct pci_conf_state *);
void pci_conf_restore(pci_chipset_tag_t, pcitag_t, struct pci_conf_state *);
int pci_get_powerstate(pci_chipset_tag_t, pcitag_t, pcireg_t *);
int pci_set_powerstate(pci_chipset_tag_t, pcitag_t, pcireg_t);
int pci_activate(pci_chipset_tag_t, pcitag_t, void *,
int (*)(pci_chipset_tag_t, pcitag_t, void *, pcireg_t));
int pci_activate_null(pci_chipset_tag_t, pcitag_t, void *, pcireg_t);
#endif /* _KERNEL */