summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorjmcneill <jmcneill@NetBSD.org>2007-12-09 20:27:42 +0000
committerjmcneill <jmcneill@NetBSD.org>2007-12-09 20:27:42 +0000
commit4c1d81b2b5fa658e9fd5e7151eb40ba71ba676da (patch)
tree3f8b0d6c63745bde8809b8c6f9e4f6b1514f335e /sys/dev
parent3947df41d16da8b387239b9b87789bfbe950a3b2 (diff)
Merge jmcneill-pm branch.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/acpi/acpi.c171
-rw-r--r--sys/dev/acpi/acpi_acad.c9
-rw-r--r--sys/dev/acpi/acpi_apm.c7
-rw-r--r--sys/dev/acpi/acpi_bat.c13
-rw-r--r--sys/dev/acpi/acpi_button.c9
-rw-r--r--sys/dev/acpi/acpi_ec.c1432
-rw-r--r--sys/dev/acpi/acpi_ecreg.h161
-rw-r--r--sys/dev/acpi/acpi_lid.c47
-rw-r--r--sys/dev/acpi/acpi_madt.c36
-rw-r--r--sys/dev/acpi/acpi_madt.h4
-rw-r--r--sys/dev/acpi/acpi_pci_link.c12
-rw-r--r--sys/dev/acpi/acpi_quirks.c37
-rw-r--r--sys/dev/acpi/acpi_tz.c11
-rw-r--r--sys/dev/acpi/acpica/OsdEnvironment.c10
-rw-r--r--sys/dev/acpi/acpica/OsdHardware.c16
-rw-r--r--sys/dev/acpi/acpica/OsdMemory.c31
-rw-r--r--sys/dev/acpi/acpica/OsdSchedule.c30
-rw-r--r--sys/dev/acpi/acpica/OsdSynch.c12
-rw-r--r--sys/dev/acpi/acpica/files.acpica9
-rw-r--r--sys/dev/acpi/acpivar.h19
-rw-r--r--sys/dev/acpi/files.acpi9
-rw-r--r--sys/dev/acpi/pckbc_acpi.c10
-rw-r--r--sys/dev/acpi/pcppi_acpi.c7
-rw-r--r--sys/dev/apm/apm.c22
-rw-r--r--sys/dev/ata/ata.c67
-rw-r--r--sys/dev/ata/atavar.h3
-rw-r--r--sys/dev/ata/wd.c48
-rw-r--r--sys/dev/ata/wdvar.h4
-rw-r--r--sys/dev/audio.c306
-rw-r--r--sys/dev/audiovar.h9
-rw-r--r--sys/dev/cardbus/cardbus.c287
-rw-r--r--sys/dev/cardbus/cardbusvar.h17
-rw-r--r--sys/dev/cardbus/cardslot.c7
-rw-r--r--sys/dev/cardbus/if_ath_cardbus.c81
-rw-r--r--sys/dev/cardbus/if_atw_cardbus.c8
-rw-r--r--sys/dev/cardbus/if_ex_cardbus.c8
-rw-r--r--sys/dev/cardbus/if_ral_cardbus.c21
-rw-r--r--sys/dev/cardbus/if_re_cardbus.c33
-rw-r--r--sys/dev/cardbus/if_rtk_cardbus.c30
-rw-r--r--sys/dev/cardbus/if_rtw_cardbus.c8
-rw-r--r--sys/dev/cardbus/if_tlp_cardbus.c7
-rw-r--r--sys/dev/dkwedge/dk.c8
-rw-r--r--sys/dev/i2c/i2c.c5
-rw-r--r--sys/dev/ic/an.c39
-rw-r--r--sys/dev/ic/anvar.h4
-rw-r--r--sys/dev/ic/ath.c78
-rw-r--r--sys/dev/ic/athvar.h7
-rw-r--r--sys/dev/ic/attimer.c7
-rw-r--r--sys/dev/ic/hpet.c28
-rw-r--r--sys/dev/ic/hpetreg.h30
-rw-r--r--sys/dev/ic/i82801lpcreg.h30
-rw-r--r--sys/dev/ic/pckbc.c21
-rw-r--r--sys/dev/ic/pckbcvar.h5
-rw-r--r--sys/dev/ic/rt2560.c85
-rw-r--r--sys/dev/ic/rt2560var.h6
-rw-r--r--sys/dev/ic/rt2661.c12
-rw-r--r--sys/dev/ic/rt2661var.h3
-rw-r--r--sys/dev/ic/rtl8169.c76
-rw-r--r--sys/dev/ic/rtl81x9.c73
-rw-r--r--sys/dev/ic/rtl81x9var.h6
-rw-r--r--sys/dev/ic/spic.c13
-rw-r--r--sys/dev/ic/vga.c12
-rw-r--r--sys/dev/ic/vga_subr.c11
-rw-r--r--sys/dev/ic/vgavar.h7
-rw-r--r--sys/dev/ic/wi.c39
-rw-r--r--sys/dev/ic/wivar.h4
-rw-r--r--sys/dev/ieee1394/firewire.c7
-rw-r--r--sys/dev/ieee1394/fwohci.c9
-rw-r--r--sys/dev/ieee1394/if_fwip.c9
-rw-r--r--sys/dev/isa/aps.c68
-rw-r--r--sys/dev/isa/isa.c7
-rw-r--r--sys/dev/isapnp/isapnp.c7
-rw-r--r--sys/dev/mii/acphy.c7
-rw-r--r--sys/dev/mii/amhphy.c7
-rw-r--r--sys/dev/mii/bmtphy.c7
-rw-r--r--sys/dev/mii/brgphy.c7
-rw-r--r--sys/dev/mii/ciphy.c7
-rw-r--r--sys/dev/mii/dmphy.c7
-rw-r--r--sys/dev/mii/exphy.c7
-rw-r--r--sys/dev/mii/gentbi.c7
-rw-r--r--sys/dev/mii/glxtphy.c7
-rw-r--r--sys/dev/mii/gphyter.c7
-rw-r--r--sys/dev/mii/icsphy.c7
-rw-r--r--sys/dev/mii/igphy.c7
-rw-r--r--sys/dev/mii/ikphy.c7
-rw-r--r--sys/dev/mii/inphy.c7
-rw-r--r--sys/dev/mii/iophy.c7
-rw-r--r--sys/dev/mii/lxtphy.c7
-rw-r--r--sys/dev/mii/makphy.c7
-rw-r--r--sys/dev/mii/mii_physubr.c13
-rw-r--r--sys/dev/mii/miivar.h3
-rw-r--r--sys/dev/mii/mvphy.c7
-rw-r--r--sys/dev/mii/nsphy.c7
-rw-r--r--sys/dev/mii/nsphyter.c7
-rw-r--r--sys/dev/mii/pnaphy.c7
-rw-r--r--sys/dev/mii/qsphy.c7
-rw-r--r--sys/dev/mii/rgephy.c7
-rw-r--r--sys/dev/mii/rlphy.c7
-rw-r--r--sys/dev/mii/sqphy.c7
-rw-r--r--sys/dev/mii/tlphy.c7
-rw-r--r--sys/dev/mii/tqphy.c7
-rw-r--r--sys/dev/mii/ukphy.c7
-rw-r--r--sys/dev/mii/urlphy.c7
-rw-r--r--sys/dev/pad/pad.c8
-rw-r--r--sys/dev/pci/agp.c18
-rw-r--r--sys/dev/pci/agp_i810.c35
-rw-r--r--sys/dev/pci/agp_intel.c48
-rw-r--r--sys/dev/pci/ahcisata_pci.c42
-rw-r--r--sys/dev/pci/auacer.c58
-rw-r--r--sys/dev/pci/auich.c111
-rw-r--r--sys/dev/pci/auixp.c92
-rw-r--r--sys/dev/pci/auixpvar.h6
-rw-r--r--sys/dev/pci/autri.c30
-rw-r--r--sys/dev/pci/autrivar.h4
-rw-r--r--sys/dev/pci/auvia.c48
-rw-r--r--sys/dev/pci/auviavar.h6
-rw-r--r--sys/dev/pci/azalia.c170
-rw-r--r--sys/dev/pci/azalia_codec.c22
-rw-r--r--sys/dev/pci/cs4280.c159
-rw-r--r--sys/dev/pci/cs4281.c141
-rw-r--r--sys/dev/pci/cs428x.h26
-rw-r--r--sys/dev/pci/ehci_pci.c51
-rw-r--r--sys/dev/pci/esa.c60
-rw-r--r--sys/dev/pci/esavar.h3
-rw-r--r--sys/dev/pci/esm.c67
-rw-r--r--sys/dev/pci/esmvar.h11
-rw-r--r--sys/dev/pci/fwohci_pci.c74
-rw-r--r--sys/dev/pci/ichsmb.c7
-rw-r--r--sys/dev/pci/if_an_pci.c14
-rw-r--r--sys/dev/pci/if_ath_pci.c109
-rw-r--r--sys/dev/pci/if_bge.c191
-rw-r--r--sys/dev/pci/if_bgereg.h8
-rw-r--r--sys/dev/pci/if_ipw.c93
-rw-r--r--sys/dev/pci/if_ipwvar.h5
-rw-r--r--sys/dev/pci/if_iwi.c112
-rw-r--r--sys/dev/pci/if_iwivar.h6
-rw-r--r--sys/dev/pci/if_nfe.c28
-rw-r--r--sys/dev/pci/if_nfevar.h3
-rw-r--r--sys/dev/pci/if_re_pci.c39
-rw-r--r--sys/dev/pci/if_rtk_pci.c76
-rw-r--r--sys/dev/pci/if_wi_pci.c28
-rw-r--r--sys/dev/pci/if_wm.c68
-rw-r--r--sys/dev/pci/if_wpi.c54
-rw-r--r--sys/dev/pci/if_wpivar.h3
-rw-r--r--sys/dev/pci/neo.c25
-rw-r--r--sys/dev/pci/ohci_pci.c9
-rw-r--r--sys/dev/pci/pccbb.c194
-rw-r--r--sys/dev/pci/pccbbvar.h7
-rw-r--r--sys/dev/pci/pci.c268
-rw-r--r--sys/dev/pci/pcidevs.h4
-rw-r--r--sys/dev/pci/pcidevs_data.h4
-rw-r--r--sys/dev/pci/pcivar.h4
-rw-r--r--sys/dev/pci/piixide.c63
-rw-r--r--sys/dev/pci/piixpm.c55
-rw-r--r--sys/dev/pci/ppb.c56
-rw-r--r--sys/dev/pci/uhci_pci.c58
-rw-r--r--sys/dev/pci/vga_pci.c24
-rw-r--r--sys/dev/pci/yds.c96
-rw-r--r--sys/dev/pckbport/pckbd.c88
-rw-r--r--sys/dev/pckbport/pms.c70
-rw-r--r--sys/dev/pckbport/wskbdmap_mfii.c7
-rw-r--r--sys/dev/pcmcia/if_an_pcmcia.c13
-rw-r--r--sys/dev/pcmcia/if_ray.c71
-rw-r--r--sys/dev/pcmcia/if_wi_pcmcia.c41
-rw-r--r--sys/dev/pcmcia/pcmcia.c9
-rw-r--r--sys/dev/rasops/rasops.c25
-rw-r--r--sys/dev/rasops/rasops8.c31
-rw-r--r--sys/dev/scsipi/atapiconf.c7
-rw-r--r--sys/dev/scsipi/cd.c8
-rw-r--r--sys/dev/scsipi/scsiconf.c8
-rw-r--r--sys/dev/scsipi/sd.c31
-rw-r--r--sys/dev/sysmon/sysmon_power.c21
-rw-r--r--sys/dev/usb/ehci.c175
-rw-r--r--sys/dev/usb/ehcivar.h5
-rw-r--r--sys/dev/usb/if_rum.c6
-rw-r--r--sys/dev/usb/ohci.c122
-rw-r--r--sys/dev/usb/ohcivar.h4
-rw-r--r--sys/dev/usb/ugen.c7
-rw-r--r--sys/dev/usb/uhci.c163
-rw-r--r--sys/dev/usb/uhcivar.h7
-rw-r--r--sys/dev/usb/uhub.c7
-rw-r--r--sys/dev/usb/umass.c9
-rw-r--r--sys/dev/usb/usb.c7
-rw-r--r--sys/dev/wscons/wsdisplay.c45
-rw-r--r--sys/dev/wscons/wskbd.c25
-rw-r--r--sys/dev/wscons/wsksymdef.h5
-rw-r--r--sys/dev/wscons/wsmouse.c7
187 files changed, 3622 insertions, 4406 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c
index bed7d0a6fb4..f94dc796ada 100644
--- a/sys/dev/acpi/acpi.c
+++ b/sys/dev/acpi/acpi.c
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi.c,v 1.103 2007/12/05 07:06:50 ad Exp $ */
+/* $NetBSD: acpi.c,v 1.104 2007/12/09 20:27:52 jmcneill Exp $ */
/*-
* Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
@@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.103 2007/12/05 07:06:50 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.104 2007/12/09 20:27:52 jmcneill Exp $");
#include "opt_acpi.h"
#include "opt_pcifixup.h"
@@ -122,6 +122,8 @@ MALLOC_DECLARE(M_ACPI);
static int acpi_dbgr = 0x00;
#endif
+static ACPI_TABLE_DESC acpi_initial_tables[128];
+
static int acpi_match(struct device *, struct cfdata *, void *);
static void acpi_attach(struct device *, struct device *, void *);
@@ -203,6 +205,9 @@ acpi_probe(void)
acpi_osd_debugger();
#endif
+ AcpiGbl_AllMethodsSerialized = FALSE;
+ AcpiGbl_EnableInterpreterSlack = TRUE;
+
rv = AcpiInitializeSubsystem();
if (ACPI_FAILURE(rv)) {
printf("ACPI: unable to initialize ACPICA: %s\n",
@@ -210,6 +215,20 @@ acpi_probe(void)
return 0;
}
+ rv = AcpiInitializeTables(acpi_initial_tables, 128, 0);
+ if (ACPI_FAILURE(rv)) {
+ printf("ACPI: unable to initialize ACPI tables: %s\n",
+ AcpiFormatException(rv));
+ return 0;
+ }
+
+ rv = AcpiReallocateRootTable();
+ if (ACPI_FAILURE(rv)) {
+ printf("ACPI: unable to reallocate root table: %s\n",
+ AcpiFormatException(rv));
+ return 0;
+ }
+
#ifdef ACPI_DEBUGGER
if (acpi_dbgr & ACPI_DBGR_TABLES)
acpi_osd_debugger();
@@ -222,7 +241,7 @@ acpi_probe(void)
return 0;
}
-
+#if notyet
if (!acpi_force_load && (acpi_find_quirks() & ACPI_QUIRK_BROKEN)) {
printf("ACPI: BIOS implementation in listed as broken:\n");
printf("ACPI: X/RSDT: OemId <%6.6s,%8.8s,%08x>, "
@@ -235,6 +254,36 @@ acpi_probe(void)
return 0;
}
+ /* Install the default address space handlers. */
+ rv = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
+ ACPI_ADR_SPACE_SYSTEM_MEMORY, ACPI_DEFAULT_HANDLER, NULL, NULL);
+ if (ACPI_FAILURE(rv)) {
+ printf("ACPI: unable to initialise SystemMemory handler: %s\n",
+ AcpiFormatException(rv));
+ return 0;
+ }
+ rv = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
+ ACPI_ADR_SPACE_SYSTEM_IO, ACPI_DEFAULT_HANDLER, NULL, NULL);
+ if (ACPI_FAILURE(rv)) {
+ printf("ACPI: unable to initialise SystemIO handler: %s\n",
+ AcpiFormatException(rv));
+ return 0;
+ }
+ rv = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
+ ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
+ if (ACPI_FAILURE(rv)) {
+ printf("ACPI: unabled to initialise PciConfig handler: %s\n",
+ AcpiFormatException(rv));
+ return 0;
+ }
+#endif
+
+ rv = AcpiEnableSubsystem(~(ACPI_NO_HARDWARE_INIT|ACPI_NO_ACPI_ENABLE));
+ if (ACPI_FAILURE(rv)) {
+ printf("ACPI: unable to enable: %s\n", AcpiFormatException(rv));
+ return 0;
+ }
+
/*
* Looks like we have ACPI!
*/
@@ -257,10 +306,10 @@ acpi_check(device_t parent, const char *ifattr)
return (config_search_ia(acpi_submatch, parent, ifattr, NULL) != NULL);
}
-ACPI_STATUS
-acpi_OsGetRootPointer(UINT32 Flags, ACPI_POINTER *PhysicalAddress)
+ACPI_PHYSICAL_ADDRESS
+acpi_OsGetRootPointer(void)
{
- ACPI_STATUS rv;
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress;
/*
* IA-32: Use AcpiFindRootPointer() to locate the RSDP.
@@ -271,13 +320,12 @@ acpi_OsGetRootPointer(UINT32 Flags, ACPI_POINTER *PhysicalAddress)
* ways to do it.
*/
- rv = acpi_md_OsGetRootPointer(Flags, PhysicalAddress);
+ PhysicalAddress = acpi_md_OsGetRootPointer();
- if (acpi_root_pointer == 0 && ACPI_SUCCESS(rv))
- acpi_root_pointer =
- (uint64_t)PhysicalAddress->Pointer.Physical;
+ if (acpi_root_pointer == 0)
+ acpi_root_pointer = PhysicalAddress;
- return rv;
+ return PhysicalAddress;
}
/*
@@ -324,11 +372,13 @@ acpi_attach(struct device *parent, struct device *self, void *aux)
aprint_verbose("%s: using Intel ACPI CA subsystem version %08x\n",
sc->sc_dev.dv_xname, ACPI_CA_VERSION);
+#if 0
aprint_verbose("%s: X/RSDT: OemId <%6.6s,%8.8s,%08x>, AslId <%4.4s,%08x>\n",
sc->sc_dev.dv_xname,
AcpiGbl_XSDT->OemId, AcpiGbl_XSDT->OemTableId,
AcpiGbl_XSDT->OemRevision,
AcpiGbl_XSDT->AslCompilerId, AcpiGbl_XSDT->AslCompilerRevision);
+#endif
sc->sc_quirks = acpi_find_quirks();
@@ -341,6 +391,12 @@ acpi_attach(struct device *parent, struct device *self, void *aux)
acpi_softc = sc;
/*
+ * Register null power management handler
+ */
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
+ /*
* Bring ACPI on-line.
*/
#ifdef ACPI_DEBUGGER
@@ -348,7 +404,22 @@ acpi_attach(struct device *parent, struct device *self, void *aux)
acpi_osd_debugger();
#endif
- rv = AcpiEnableSubsystem(0);
+#define ACPI_ENABLE_PHASE1 \
+ (ACPI_NO_HANDLER_INIT | ACPI_NO_EVENT_INIT)
+#define ACPI_ENABLE_PHASE2 \
+ (ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE | \
+ ACPI_NO_ADDRESS_SPACE_INIT)
+
+ rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE1);
+ if (ACPI_FAILURE(rv)) {
+ aprint_error("%s: unable to enable ACPI: %s\n",
+ sc->sc_dev.dv_xname, AcpiFormatException(rv));
+ return;
+ }
+
+ acpi_md_callback();
+
+ rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE2);
if (ACPI_FAILURE(rv)) {
aprint_error("%s: unable to enable ACPI: %s\n",
sc->sc_dev.dv_xname, AcpiFormatException(rv));
@@ -356,11 +427,9 @@ acpi_attach(struct device *parent, struct device *self, void *aux)
}
/* early EC handler initialization if ECDT table is available */
-#if NACPIEC > 0
- acpiec_early_attach(&sc->sc_dev);
-#endif
+ config_found_ia(&sc->sc_dev, "acpiecdtbus", NULL, NULL);
- rv = AcpiInitializeObjects(0);
+ rv = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION);
if (ACPI_FAILURE(rv)) {
aprint_error("%s: unable to initialize ACPI objects: %s\n",
sc->sc_dev.dv_xname, AcpiFormatException(rv));
@@ -372,9 +441,9 @@ acpi_attach(struct device *parent, struct device *self, void *aux)
sc->sc_sleepstate = ACPI_STATE_S0;
/* Show SCI interrupt. */
- if (AcpiGbl_FADT != NULL)
- aprint_verbose("%s: SCI interrupting at int %d\n",
- sc->sc_dev.dv_xname, AcpiGbl_FADT->SciInt);
+ aprint_verbose("%s: SCI interrupting at int %d\n",
+ sc->sc_dev.dv_xname, AcpiGbl_FADT.SciInterrupt);
+
/*
* Check for fixed-hardware features.
*/
@@ -388,7 +457,6 @@ acpi_attach(struct device *parent, struct device *self, void *aux)
if (acpi_dbgr & ACPI_DBGR_PROBE)
acpi_osd_debugger();
#endif
- acpi_md_callback((struct device *)sc);
acpi_build_tree(sc);
if (acpi_root_pointer != 0 && acpi_node != CTL_EOL) {
@@ -529,15 +597,18 @@ acpi_build_tree(struct acpi_softc *sc)
(ACPI_STA_DEV_PRESENT|ACPI_STA_DEV_ENABLED|
ACPI_STA_DEV_OK))
continue;
-
- /*
- * XXX Same problem as above...
- */
- if ((ad->ad_devinfo->Valid & ACPI_VALID_HID)
- == 0)
- continue;
}
+ /*
+ * XXX Same problem as above...
+ *
+ * Do this check only for devices, as e.g.
+ * a Thermal Zone doesn't have a HID.
+ */
+ if (ad->ad_devinfo->Type == ACPI_TYPE_DEVICE &&
+ (ad->ad_devinfo->Valid & ACPI_VALID_HID) == 0)
+ continue;
+
ad->ad_device = config_found_ia(&sc->sc_dev,
"acpinodebus", &aa, acpi_print);
}
@@ -658,7 +729,8 @@ acpi_make_devnode(ACPI_HANDLE handle, UINT32 level, void *context,
TAILQ_INSERT_TAIL(&as->as_devnodes, ad, ad_list);
- if ((ad->ad_devinfo->Valid & ACPI_VALID_HID) == 0)
+ if (type == ACPI_TYPE_DEVICE &&
+ (ad->ad_devinfo->Valid & ACPI_VALID_HID) == 0)
goto out;
#ifdef ACPI_EXTRA_DEBUG
@@ -722,13 +794,15 @@ acpi_print(void *aux, const char *pnp)
}
#endif
- } else {
+ aprint_normal("at %s", pnp);
+ } else if (aa->aa_node->ad_devinfo->Type != ACPI_TYPE_DEVICE) {
aprint_normal("%s (ACPI Object Type '%s' "
"[0x%02x]) ", aa->aa_node->ad_name,
AcpiUtGetTypeName(aa->aa_node->ad_devinfo->Type),
aa->aa_node->ad_devinfo->Type);
- }
- aprint_normal("at %s", pnp);
+ aprint_normal("at %s", pnp);
+ } else
+ return 0;
} else {
aprint_normal(" (%s", aa->aa_node->ad_name);
if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_HID) {
@@ -773,7 +847,7 @@ acpi_enable_fixed_events(struct acpi_softc *sc)
* Check for fixed-hardware buttons.
*/
- if (AcpiGbl_FADT != NULL && AcpiGbl_FADT->PwrButton == 0) {
+ if ((AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) == 0) {
aprint_verbose("%s: fixed-feature power button present\n",
sc->sc_dev.dv_xname);
sc->sc_smpsw_power.smpsw_name = sc->sc_dev.dv_xname;
@@ -794,7 +868,7 @@ acpi_enable_fixed_events(struct acpi_softc *sc)
}
}
- if (AcpiGbl_FADT != NULL && AcpiGbl_FADT->SleepButton == 0) {
+ if ((AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
aprint_verbose("%s: fixed-feature sleep button present\n",
sc->sc_dev.dv_xname);
sc->sc_smpsw_sleep.smpsw_name = sc->sc_dev.dv_xname;
@@ -831,7 +905,7 @@ acpi_fixed_button_handler(void *context)
printf("%s: fixed button handler\n", smpsw->smpsw_name);
#endif
- rv = AcpiOsQueueForExecution(OSD_PRIORITY_LO,
+ rv = AcpiOsExecute(OSL_NOTIFY_HANDLER,
acpi_fixed_button_pressed, smpsw);
if (ACPI_FAILURE(rv))
printf("%s: WARNING: unable to queue fixed button pressed "
@@ -1085,7 +1159,7 @@ is_available_state(struct acpi_softc *sc, int state)
ACPI_STATUS
acpi_enter_sleep_state(struct acpi_softc *sc, int state)
{
- int s;
+ int err;
ACPI_STATUS ret = AE_OK;
if (state == acpi_sleepstate)
@@ -1105,32 +1179,33 @@ acpi_enter_sleep_state(struct acpi_softc *sc, int state)
sc->sc_dev.dv_xname, state);
break;
}
+
+ if (state != ACPI_STATE_S1 && !pmf_system_suspend()) {
+ aprint_error_dev(&sc->sc_dev, "aborting suspend");
+ break;
+ }
+
ret = AcpiEnterSleepStatePrep(state);
if (ACPI_FAILURE(ret)) {
aprint_error("%s: failed preparing to sleep (%s)\n",
sc->sc_dev.dv_xname, AcpiFormatException(ret));
break;
}
+
acpi_sleepstate = state;
if (state == ACPI_STATE_S1) {
/* just enter the state */
acpi_md_OsDisableInterrupt();
AcpiEnterSleepState((UINT8)state);
+ AcpiLeaveSleepState((UINT8)state);
} else {
- /* XXX: powerhooks(9) framework is too poor to
- * support ACPI sleep state...
- */
- dopowerhooks(PWR_SOFTSUSPEND);
- s = splhigh();
- dopowerhooks(PWR_SUSPEND);
- acpi_md_sleep(state);
- dopowerhooks(PWR_RESUME);
- splx(s);
- dopowerhooks(PWR_SOFTRESUME);
- if (state==ACPI_STATE_S4)
+ err = acpi_md_sleep(state);
+ if (state == ACPI_STATE_S4)
AcpiEnable();
+ AcpiLeaveSleepState((UINT8)state);
+ pmf_system_resume();
}
- AcpiLeaveSleepState((UINT8)state);
+
break;
case ACPI_STATE_S5:
ret = AcpiEnterSleepStatePrep(ACPI_STATE_S5);
@@ -1139,6 +1214,7 @@ acpi_enter_sleep_state(struct acpi_softc *sc, int state)
sc->sc_dev.dv_xname, AcpiFormatException(ret));
break;
}
+ DELAY(1000000);
acpi_sleepstate = state;
acpi_md_OsDisableInterrupt();
AcpiEnterSleepState(ACPI_STATE_S5);
@@ -1147,7 +1223,6 @@ acpi_enter_sleep_state(struct acpi_softc *sc, int state)
break;
}
- aprint_normal("%s: resuming\n", sc->sc_dev.dv_xname);
acpi_sleepstate = ACPI_STATE_S0;
return ret;
}
diff --git a/sys/dev/acpi/acpi_acad.c b/sys/dev/acpi/acpi_acad.c
index da2e9154292..9b762ccc462 100644
--- a/sys/dev/acpi/acpi_acad.c
+++ b/sys/dev/acpi/acpi_acad.c
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_acad.c,v 1.30 2007/12/05 07:06:50 ad Exp $ */
+/* $NetBSD: acpi_acad.c,v 1.31 2007/12/09 20:27:52 jmcneill Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -44,7 +44,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_acad.c,v 1.30 2007/12/05 07:06:50 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_acad.c,v 1.31 2007/12/09 20:27:52 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -151,6 +151,9 @@ acpiacad_attach(device_t parent, device_t self, void *aux)
sc->sc_flags = AACAD_F_VERBOSE;
#endif
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
acpiacad_init_envsys(self);
}
@@ -247,7 +250,7 @@ acpiacad_notify_handler(ACPI_HANDLE handle, UINT32 notify, void *context)
acpiacad_clear_status(sc);
mutex_exit(&sc->sc_mtx);
if (sc->sc_status == -1 || !sc->sc_notifysent) {
- rv = AcpiOsQueueForExecution(OSD_PRIORITY_LO,
+ rv = AcpiOsExecute(OSL_NOTIFY_HANDLER,
acpiacad_get_status, dv);
if (ACPI_FAILURE(rv))
aprint_error_dev(dv,
diff --git a/sys/dev/acpi/acpi_apm.c b/sys/dev/acpi/acpi_apm.c
index 64ece3a11ed..e69b2772356 100644
--- a/sys/dev/acpi/acpi_apm.c
+++ b/sys/dev/acpi/acpi_apm.c
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_apm.c,v 1.11 2007/10/27 19:51:29 plunky Exp $ */
+/* $NetBSD: acpi_apm.c,v 1.12 2007/12/09 20:27:52 jmcneill Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_apm.c,v 1.11 2007/10/27 19:51:29 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_apm.c,v 1.12 2007/12/09 20:27:52 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -337,7 +337,8 @@ acpiapm_get_powstat(void *opaque, u_int batteryid,
else if (strstr(desc, " design cap"))
descap = data / 1000;
else if (strstr(desc, " charge") &&
- strstr(desc, " charge rate") == NULL) {
+ strstr(desc, " charge rate") == NULL &&
+ strstr(desc, " charge state") == NULL) {
cap += data / 1000;
cap_valid = 1;
pinfo->nbattery++;
diff --git a/sys/dev/acpi/acpi_bat.c b/sys/dev/acpi/acpi_bat.c
index ea32f286a71..e9778224a80 100644
--- a/sys/dev/acpi/acpi_bat.c
+++ b/sys/dev/acpi/acpi_bat.c
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_bat.c,v 1.63 2007/12/05 07:06:50 ad Exp $ */
+/* $NetBSD: acpi_bat.c,v 1.64 2007/12/09 20:27:52 jmcneill Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -86,7 +86,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_bat.c,v 1.63 2007/12/05 07:06:50 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_bat.c,v 1.64 2007/12/09 20:27:52 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -239,6 +239,9 @@ acpibat_attach(device_t parent, device_t self, void *aux)
ABAT_SET(sc, ABAT_F_VERBOSE);
#endif
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
acpibat_init_envsys(self);
}
@@ -648,8 +651,7 @@ acpibat_notify_handler(ACPI_HANDLE handle, UINT32 notify, void *context)
mutex_enter(&sc->sc_mtx);
acpibat_clear_presence(sc);
mutex_exit(&sc->sc_mtx);
- rv = AcpiOsQueueForExecution(OSD_PRIORITY_LO,
- acpibat_update, dv);
+ rv = AcpiOsExecute(OSL_NOTIFY_HANDLER, acpibat_update, dv);
if (ACPI_FAILURE(rv))
aprint_error_dev(dv,
"unable to queue status check: %s\n",
@@ -660,8 +662,7 @@ acpibat_notify_handler(ACPI_HANDLE handle, UINT32 notify, void *context)
mutex_enter(&sc->sc_mtx);
acpibat_clear_stat(sc);
mutex_exit(&sc->sc_mtx);
- rv = AcpiOsQueueForExecution(OSD_PRIORITY_LO,
- acpibat_update, dv);
+ rv = AcpiOsExecute(OSL_NOTIFY_HANDLER, acpibat_update, dv);
if (ACPI_FAILURE(rv))
aprint_error_dev(dv,
"unable to queue status check: %s\n",
diff --git a/sys/dev/acpi/acpi_button.c b/sys/dev/acpi/acpi_button.c
index d38e7bf5f70..9a68ab11057 100644
--- a/sys/dev/acpi/acpi_button.c
+++ b/sys/dev/acpi/acpi_button.c
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_button.c,v 1.24 2007/10/24 07:05:35 joerg Exp $ */
+/* $NetBSD: acpi_button.c,v 1.25 2007/12/09 20:27:52 jmcneill Exp $ */
/*
* Copyright 2001, 2003 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_button.c,v 1.24 2007/10/24 07:05:35 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_button.c,v 1.25 2007/12/09 20:27:52 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -151,6 +151,9 @@ acpibut_attach(device_t parent, device_t self, void *aux)
/* Display the current state when it changes. */
sc->sc_flags = ACPIBUT_F_VERBOSE;
#endif
+
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
/*
@@ -189,7 +192,7 @@ acpibut_notify_handler(ACPI_HANDLE handle, UINT32 notify, void *context)
#ifdef ACPI_BUT_DEBUG
aprint_debug_dev(dv, "received ButtonPressed message\n");
#endif
- rv = AcpiOsQueueForExecution(OSD_PRIORITY_LO,
+ rv = AcpiOsExecute(OSL_NOTIFY_HANDLER,
acpibut_pressed_event, dv);
if (ACPI_FAILURE(rv))
aprint_error_dev(dv,
diff --git a/sys/dev/acpi/acpi_ec.c b/sys/dev/acpi/acpi_ec.c
index 62dd477ab51..c3e686ff68f 100644
--- a/sys/dev/acpi/acpi_ec.c
+++ b/sys/dev/acpi/acpi_ec.c
@@ -1,355 +1,207 @@
-/* $NetBSD: acpi_ec.c,v 1.43 2007/12/05 07:58:29 ad Exp $ */
-
-/*
- * Copyright 2001 Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Written by Jason R. Thorpe for Wasabi Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Wasabi Systems, Inc.
- * 4. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
+/* $NetBSD: acpi_ec.c,v 1.44 2007/12/09 20:27:52 jmcneill Exp $ */
/*-
- * Copyright (c) 2000 Michael Smith
- * Copyright (c) 2000 BSDi
+ * Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
+ *
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-/******************************************************************************
- *
- * 1. Copyright Notice
- *
- * Some or all of this work - Copyright (c) 1999, Intel Corp. All rights
- * reserved.
- *
- * 2. License
- *
- * 2.1. This is your license from Intel Corp. under its intellectual property
- * rights. You may have additional license terms from the party that provided
- * you this software, covering your right to use that party's intellectual
- * property rights.
- *
- * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
- * copy of the source code appearing in this file ("Covered Code") an
- * irrevocable, perpetual, worldwide license under Intel's copyrights in the
- * base code distributed originally by Intel ("Original Intel Code") to copy,
- * make derivatives, distribute, use and display any portion of the Covered
- * Code in any form, with the right to sublicense such rights; and
- *
- * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
- * license (with the right to sublicense), under only those claims of Intel
- * patents that are infringed by the Original Intel Code, to make, use, sell,
- * offer to sell, and import the Covered Code and derivative works thereof
- * solely to the minimum extent necessary to exercise the above copyright
- * license, and in no event shall the patent license extend to any additions
- * to or modifications of the Original Intel Code. No other license or right
- * is granted directly or by implication, estoppel or otherwise;
- *
- * The above copyright and patent license is granted only if the following
- * conditions are met:
- *
- * 3. Conditions
- *
- * 3.1. Redistribution of Source with Rights to Further Distribute Source.
- * Redistribution of source code of any substantial portion of the Covered
- * Code or modification with rights to further distribute source must include
- * the above Copyright Notice, the above License, this list of Conditions,
- * and the following Disclaimer and Export Compliance provision. In addition,
- * Licensee must cause all Covered Code to which Licensee contributes to
- * contain a file documenting the changes Licensee made to create that Covered
- * Code and the date of any change. Licensee must include in that file the
- * documentation of any changes made by any predecessor Licensee. Licensee
- * must include a prominent statement that the modification is derived,
- * directly or indirectly, from Original Intel Code.
- *
- * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
- * Redistribution of source code of any substantial portion of the Covered
- * Code or modification without rights to further distribute source must
- * include the following Disclaimer and Export Compliance provision in the
- * documentation and/or other materials provided with distribution. In
- * addition, Licensee may not authorize further sublicense of source of any
- * portion of the Covered Code, and must include terms to the effect that the
- * license from Licensee to its licensee is limited to the intellectual
- * property embodied in the software Licensee provides to its licensee, and
- * not to intellectual property embodied in modifications its licensee may
- * make.
- *
- * 3.3. Redistribution of Executable. Redistribution in executable form of any
- * substantial portion of the Covered Code or modification must reproduce the
- * above Copyright Notice, and the following Disclaimer and Export Compliance
- * provision in the documentation and/or other materials provided with the
- * distribution.
- *
- * 3.4. Intel retains all right, title, and interest in and to the Original
- * Intel Code.
- *
- * 3.5. Neither the name Intel nor any other trademark owned or controlled by
- * Intel shall be used in advertising or otherwise to promote the sale, use or
- * other dealings in products derived from or relating to the Covered Code
- * without prior written authorization from Intel.
- *
- * 4. Disclaimer and Export Compliance
- *
- * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
- * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
- * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
- * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
- * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
- * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
- * PARTICULAR PURPOSE.
- *
- * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
- * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
- * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
- * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
- * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
- * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
- * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
- * LIMITED REMEDY.
- *
- * 4.3. Licensee shall not export, either directly or indirectly, any of this
- * software or system incorporating such software without first obtaining any
- * required license or other approval from the U. S. Department of Commerce or
- * any other agency or department of the United States Government. In the
- * event Licensee exports any such software from the United States or
- * re-exports any such software from a foreign destination, Licensee shall
- * ensure that the distribution and export/re-export of the software is in
- * compliance with all laws, regulations, orders, or other restrictions of the
- * U.S. Export Administration Regulations. Licensee agrees that neither it nor
- * any of its subsidiaries will export/re-export any technical data, process,
- * software, or service, directly or indirectly, to any country for which the
- * United States government or any agency thereof requires an export license,
- * other governmental approval, or letter of assurance, without first obtaining
- * such license, approval or letter.
- *
- *****************************************************************************/
-
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_ec.c,v 1.43 2007/12/05 07:58:29 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_ec.c,v 1.44 2007/12/09 20:27:52 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/condvar.h>
#include <sys/device.h>
-#include <sys/malloc.h>
-#include <sys/proc.h>
#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/mutex.h>
#include <sys/bus.h>
-#include <dev/acpi/acpica.h>
-#include <dev/acpi/acpireg.h>
#include <dev/acpi/acpivar.h>
-#include <dev/acpi/acpi_ecreg.h>
-MALLOC_DECLARE(M_ACPI);
+/* Maximum time to wait for global ACPI lock in ms */
+#define EC_LOCK_TIMEOUT 5
+
+/* Maximum time to poll for completion of a command in ms */
+#define EC_POLL_TIMEOUT 5
+
+/* From ACPI 3.0b, chapter 12.3 */
+#define EC_COMMAND_READ 0x80
+#define EC_COMMAND_WRITE 0x81
+#define EC_COMMAND_BURST_EN 0x82
+#define EC_COMMAND_BURST_DIS 0x83
+#define EC_COMMAND_QUERY 0x84
-#define _COMPONENT ACPI_EC_COMPONENT
-ACPI_MODULE_NAME("EC")
+/* From ACPI 3.0b, chapter 12.2.1 */
+#define EC_STATUS_OBF 0x01
+#define EC_STATUS_IBF 0x02
+#define EC_STATUS_CMD 0x08
+#define EC_STATUS_BURST 0x10
+#define EC_STATUS_SCI 0x20
+#define EC_STATUS_SMI 0x40
-struct acpi_ec_softc {
- struct device sc_dev; /* base device glue */
- ACPI_HANDLE sc_handle; /* ACPI handle */
+static const char *ec_hid[] = {
+ "PNP0C09",
+ NULL,
+};
- UINT32 sc_gpebit; /* our GPE interrupt bit */
+enum ec_state_t {
+ EC_STATE_QUERY,
+ EC_STATE_QUERY_VAL,
+ EC_STATE_READ,
+ EC_STATE_READ_ADDR,
+ EC_STATE_READ_VAL,
+ EC_STATE_WRITE,
+ EC_STATE_WRITE_ADDR,
+ EC_STATE_WRITE_VAL,
+ EC_STATE_FREE
+};
- bus_space_tag_t sc_data_st; /* space tag for data register */
- bus_space_handle_t sc_data_sh; /* space handle for data register */
+struct acpiec_softc {
+ ACPI_HANDLE sc_ech;
- bus_space_tag_t sc_csr_st; /* space tag for control register */
- bus_space_handle_t sc_csr_sh; /* space handle for control register */
+ ACPI_HANDLE sc_gpeh;
+ UINT8 sc_gpebit;
- int sc_flags; /* see below */
+ bus_space_tag_t sc_data_st;
+ bus_space_handle_t sc_data_sh;
- uint32_t sc_csrvalue; /* saved control register */
- uint32_t sc_uid; /* _UID in namespace (ECDT only) */
+ bus_space_tag_t sc_csr_st;
+ bus_space_handle_t sc_csr_sh;
- kmutex_t sc_lock; /* serialize operations to this EC */
- struct simplelock sc_slock; /* protect against interrupts */
- UINT32 sc_glkhandle; /* global lock handle */
- UINT32 sc_glk; /* need global lock? */
-};
+ bool sc_need_global_lock;
+ UINT32 sc_global_lock;
-static const char * const ec_hid[] = {
- "PNP0C09",
- NULL
+ kmutex_t sc_mtx, sc_access_mtx;
+ kcondvar_t sc_cv, sc_cv_sci;
+ enum ec_state_t sc_state;
+ bool sc_got_sci;
+
+ uint8_t sc_cur_addr, sc_cur_val;
};
-#define EC_F_TRANSACTION 0x01 /* doing transaction */
-#define EC_F_PENDQUERY 0x02 /* query is pending */
+static int acpiecdt_match(device_t, struct cfdata *, void *);
+static void acpiecdt_attach(device_t, device_t, void *);
-/*
- * how long to wait to acquire global lock.
- * the value is taken from FreeBSD driver.
- */
-#define EC_LOCK_TIMEOUT 1000
-
-#define EC_DATA_READ(sc) \
- bus_space_read_1((sc)->sc_data_st, (sc)->sc_data_sh, 0)
-#define EC_DATA_WRITE(sc, v) \
- bus_space_write_1((sc)->sc_data_st, (sc)->sc_data_sh, 0, (v))
-
-#define EC_CSR_READ(sc) \
- bus_space_read_1((sc)->sc_csr_st, (sc)->sc_csr_sh, 0)
-#define EC_CSR_WRITE(sc, v) \
- bus_space_write_1((sc)->sc_csr_st, (sc)->sc_csr_sh, 0, (v))
-
-typedef struct {
- EC_COMMAND Command;
- UINT8 Address;
- UINT8 Data;
-} EC_REQUEST;
-
-static UINT32 EcGpeHandler(void *);
-static ACPI_STATUS EcSpaceSetup(ACPI_HANDLE, UINT32, void *, void **);
-static ACPI_STATUS EcSpaceHandler(UINT32, ACPI_PHYSICAL_ADDRESS, UINT32,
- ACPI_INTEGER *, void *, void *);
-
-static ACPI_STATUS EcWaitEvent(struct acpi_ec_softc *, EC_EVENT);
-static ACPI_STATUS EcQuery(struct acpi_ec_softc *, UINT8 *);
-static ACPI_STATUS EcTransaction(struct acpi_ec_softc *, EC_REQUEST *);
-static ACPI_STATUS EcRead(struct acpi_ec_softc *, UINT8, UINT8 *);
-static ACPI_STATUS EcWrite(struct acpi_ec_softc *, UINT8, UINT8 *);
-static void EcGpeQueryHandler(void *);
-static inline int EcIsLocked(struct acpi_ec_softc *);
-static inline void EcLock(struct acpi_ec_softc *);
-static inline void EcUnlock(struct acpi_ec_softc *);
-
-
-static int acpiec_match(struct device *, struct cfdata *, void *);
-static void acpiec_attach(struct device *, struct device *, void *);
-
-CFATTACH_DECL(acpiec, sizeof(struct acpi_ec_softc),
+static int acpiec_match(device_t, struct cfdata *, void *);
+static void acpiec_attach(device_t, device_t, void *);
+
+static void acpiec_common_attach(device_t, device_t, ACPI_HANDLE,
+ bus_addr_t, bus_addr_t, ACPI_HANDLE, uint8_t);
+
+static bool acpiec_resume(device_t);
+static bool acpiec_suspend(device_t);
+
+static bool acpiec_parse_gpe_package(device_t, ACPI_HANDLE,
+ ACPI_HANDLE *, uint8_t *);
+
+static void acpiec_gpe_query(void *);
+static UINT32 acpiec_gpe_handler(void *);
+static ACPI_STATUS acpiec_space_setup(ACPI_HANDLE, UINT32, void *, void **);
+static ACPI_STATUS acpiec_space_handler(UINT32, ACPI_PHYSICAL_ADDRESS,
+ UINT32, ACPI_INTEGER *, void *, void *);
+
+static void acpiec_gpe_state_maschine(device_t);
+
+CFATTACH_DECL_NEW(acpiec, sizeof(struct acpiec_softc),
acpiec_match, acpiec_attach, NULL, NULL);
-static struct acpi_ec_softc *ecdt_sc;
+CFATTACH_DECL_NEW(acpiecdt, sizeof(struct acpiec_softc),
+ acpiecdt_match, acpiecdt_attach, NULL, NULL);
-static inline int
-EcIsLocked(struct acpi_ec_softc *sc)
+static device_t ec_singleton = NULL;
+static bool acpiec_cold = false;
+
+static bool
+acpiecdt_find(device_t parent, ACPI_HANDLE *ec_handle,
+ bus_addr_t *cmd_reg, bus_addr_t *data_reg, uint8_t *gpebit)
{
+ ACPI_TABLE_ECDT *ecdt;
+ ACPI_STATUS rv;
+
+ rv = AcpiGetTable(ACPI_SIG_ECDT, 1, (ACPI_TABLE_HEADER **)&ecdt);
+ if (ACPI_FAILURE(rv))
+ return false;
- return (mutex_owned(&sc->sc_lock));
+ if (ecdt->Control.BitWidth != 8 || ecdt->Data.BitWidth != 8) {
+ aprint_error_dev(parent,
+ "ECDT register width invalid (%d/%d)\n",
+ ecdt->Control.BitWidth, ecdt->Data.BitWidth);
+ return false;
+ }
+
+ rv = AcpiGetHandle(ACPI_ROOT_OBJECT, ecdt->Id, ec_handle);
+ if (ACPI_FAILURE(rv)) {
+ aprint_error_dev(parent,
+ "failed to look up EC object %s: %s\n",
+ ecdt->Id, AcpiFormatException(rv));
+ return false;
+ }
+
+ *cmd_reg = ecdt->Control.Address;
+ *data_reg = ecdt->Data.Address;
+ *gpebit = ecdt->Gpe;
+
+ return true;
}
-static inline void
-EcLock(struct acpi_ec_softc *sc)
+static int
+acpiecdt_match(device_t parent, struct cfdata *match, void *aux)
{
- ACPI_STATUS rv;
- int s;
-
- mutex_enter(&sc->sc_lock);
- if (sc->sc_glk) {
- rv = AcpiAcquireGlobalLock(EC_LOCK_TIMEOUT,
- &sc->sc_glkhandle);
- if (ACPI_FAILURE(rv)) {
- printf("%s: failed to acquire global lock\n",
- sc->sc_dev.dv_xname);
- mutex_exit(&sc->sc_lock);
- return;
- }
- }
+ ACPI_HANDLE ec_handle;
+ bus_addr_t cmd_reg, data_reg;
+ uint8_t gpebit;
- s = splvm(); /* XXX */
- simple_lock(&sc->sc_slock);
- sc->sc_flags |= EC_F_TRANSACTION;
- simple_unlock(&sc->sc_slock);
- splx(s);
+ if (acpiecdt_find(parent, &ec_handle, &cmd_reg, &data_reg, &gpebit))
+ return 1;
+ else
+ return 0;
}
-static inline void
-EcUnlock(struct acpi_ec_softc *sc)
+static void
+acpiecdt_attach(device_t parent, device_t self, void *aux)
{
- ACPI_STATUS rv;
- int s;
+ ACPI_HANDLE ec_handle;
+ bus_addr_t cmd_reg, data_reg;
+ uint8_t gpebit;
- /*
- * Clear & Re-Enable the EC GPE:
- * -----------------------------
- * 'Consume' any EC GPE events that we generated while performing
- * the transaction (e.g. IBF/OBF). Clearing the GPE here shouldn't
- * have an adverse affect on outstanding EC-SCI's, as the source
- * (EC-SCI) will still be high and thus should trigger the GPE
- * immediately after we re-enabling it.
- */
- s = splvm(); /* XXX */
- simple_lock(&sc->sc_slock);
- if (sc->sc_flags & EC_F_PENDQUERY) {
- ACPI_STATUS rv2;
-
- rv2 = AcpiOsQueueForExecution(OSD_PRIORITY_HIGH,
- EcGpeQueryHandler, sc);
- if (ACPI_FAILURE(rv2))
- printf("%s: unable to queue pending query: %s\n",
- sc->sc_dev.dv_xname, AcpiFormatException(rv2));
- sc->sc_flags &= ~EC_F_PENDQUERY;
- }
- sc->sc_flags &= ~EC_F_TRANSACTION;
- simple_unlock(&sc->sc_slock);
- splx(s);
-
- if (sc->sc_glk) {
- rv = AcpiReleaseGlobalLock(sc->sc_glkhandle);
- if (ACPI_FAILURE(rv))
- printf("%s: failed to release global lock\n",
- sc->sc_dev.dv_xname);
- }
- mutex_exit(&sc->sc_lock);
+ if (!acpiecdt_find(parent, &ec_handle, &cmd_reg, &data_reg, &gpebit))
+ panic("ECDT disappeared");
+
+ aprint_naive(": ACPI Embedded Controller via ECDT\n");
+ aprint_normal(": ACPI Embedded Controller via ECDT\n");
+
+ acpiec_common_attach(parent, self, ec_handle, cmd_reg, data_reg,
+ NULL, gpebit);
}
-/*
- * acpiec_match:
- *
- * Autoconfiguration `match' routine.
- */
static int
-acpiec_match(struct device *parent, struct cfdata *match,
- void *aux)
+acpiec_match(device_t parent, struct cfdata *match, void *aux)
{
struct acpi_attach_args *aa = aux;
@@ -359,672 +211,596 @@ acpiec_match(struct device *parent, struct cfdata *match,
return acpi_match_hid(aa->aa_node->ad_devinfo, ec_hid);
}
-void
-acpiec_early_attach(struct device *parent)
+static void
+acpiec_attach(device_t parent, device_t self, void *aux)
{
- struct acpi_softc *sc = (struct acpi_softc *)parent;
- EC_BOOT_RESOURCES *ep;
- ACPI_HANDLE handle;
+ struct acpi_attach_args *aa = aux;
+ struct acpi_resources ec_res;
+ struct acpi_io *io0, *io1;
+ ACPI_HANDLE gpe_handle;
+ uint8_t gpebit;
ACPI_STATUS rv;
- ACPI_INTEGER tmp;
- rv = AcpiGetFirmwareTable("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
- (void *)&ep);
- if (ACPI_FAILURE(rv))
+ if (ec_singleton != NULL) {
+ aprint_naive(": ACPI Embedded Controller (disabled)\n");
+ aprint_normal(": ACPI Embedded Controller (disabled)\n");
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
return;
+ }
+
+ aprint_naive(": ACPI Embedded Controller\n");
+ aprint_normal(": ACPI Embedded Controller\n");
- if (ep->EcControl.RegisterBitWidth != 8 ||
- ep->EcData.RegisterBitWidth != 8) {
- printf("%s: ECDT data is invalid, RegisterBitWidth=%d/%d\n",
- parent->dv_xname,
- ep->EcControl.RegisterBitWidth,
- ep->EcData.RegisterBitWidth);
+ if (!acpiec_parse_gpe_package(self, aa->aa_node->ad_handle,
+ &gpe_handle, &gpebit))
return;
- }
- rv = AcpiGetHandle(ACPI_ROOT_OBJECT, ep->EcId, &handle);
- if (ACPI_FAILURE(rv)) {
- printf("%s: failed to look up EC object %s: %s\n",
- parent->dv_xname,
- ep->EcId, AcpiFormatException(rv));
+ rv = acpi_resource_parse(self, aa->aa_node->ad_handle, "_CRS",
+ &ec_res, &acpi_resource_parse_ops_default);
+ if (rv != AE_OK) {
+ aprint_error_dev(self, "resource parsing failed: %s\n",
+ AcpiFormatException(rv));
return;
}
- ecdt_sc = malloc(sizeof(*ecdt_sc), M_ACPI, M_ZERO);
+ if ((io0 = acpi_res_io(&ec_res, 0)) == NULL) {
+ aprint_error_dev(self, "no data register resource\n");
+ goto free_res;
+ }
+ if ((io1 = acpi_res_io(&ec_res, 1)) == NULL) {
+ aprint_error_dev(self, "no CSR register resource\n");
+ goto free_res;
+ }
- strcpy(ecdt_sc->sc_dev.dv_xname, "acpiecdt0"); /* XXX */
- ecdt_sc->sc_handle = handle;
+ acpiec_common_attach(parent, self, aa->aa_node->ad_handle,
+ io1->ar_base, io0->ar_base, gpe_handle, gpebit);
- ecdt_sc->sc_gpebit = ep->GpeBit;
- ecdt_sc->sc_uid = ep->Uid;
+free_res:
+ acpi_resource_cleanup(&ec_res);
+}
- ecdt_sc->sc_data_st = sc->sc_iot;
- if (bus_space_map(ecdt_sc->sc_data_st,
- (bus_addr_t)(ep->EcData.Address), 1, 0,
- &ecdt_sc->sc_data_sh) != 0) {
- printf("%s: bus_space_map failed for EC data.\n",
- parent->dv_xname);
- goto out1;
- }
+static void
+acpiec_common_attach(device_t parent, device_t self,
+ ACPI_HANDLE ec_handle, bus_addr_t cmd_reg, bus_addr_t data_reg,
+ ACPI_HANDLE gpe_handle, uint8_t gpebit)
+{
+ struct acpiec_softc *sc = device_private(self);
+ ACPI_STATUS rv;
+ ACPI_INTEGER val;
- ecdt_sc->sc_csr_st = sc->sc_iot;
- if (bus_space_map(ecdt_sc->sc_csr_st,
- (bus_addr_t)(ep->EcControl.Address), 1, 0,
- &ecdt_sc->sc_csr_sh) != 0) {
- printf("%s: bus_space_map failed for EC control.\n",
- parent->dv_xname);
- goto out2;
- }
+ sc->sc_ech = ec_handle;
+ sc->sc_gpeh = gpe_handle;
+ sc->sc_gpebit = gpebit;
- rv = acpi_eval_integer(handle, "_GLK", &tmp);
- if (ACPI_SUCCESS(rv) && tmp == 1)
- ecdt_sc->sc_glk = 1;
+ sc->sc_state = EC_STATE_FREE;
+ mutex_init(&sc->sc_mtx, MUTEX_DRIVER, IPL_TTY);
+ mutex_init(&sc->sc_access_mtx, MUTEX_DEFAULT, IPL_NONE);
+ cv_init(&sc->sc_cv, "eccv");
+ cv_init(&sc->sc_cv_sci, "ecsci");
- rv = AcpiInstallGpeHandler(NULL, ecdt_sc->sc_gpebit,
- ACPI_GPE_EDGE_TRIGGERED, EcGpeHandler, ecdt_sc);
- if (ACPI_FAILURE(rv)) {
- printf("%s: unable to install GPE handler: %s\n",
- parent->dv_xname, AcpiFormatException(rv));
- goto out3;
+ if (bus_space_map(sc->sc_data_st, data_reg, 1, 0,
+ &sc->sc_data_sh) != 0) {
+ aprint_error_dev(self, "unable to map data register\n");
+ return;
}
- rv = AcpiSetGpeType(NULL, ecdt_sc->sc_gpebit, ACPI_GPE_TYPE_RUNTIME);
- if (ACPI_FAILURE(rv)) {
- printf("%s: unable to set GPE type: %s\n",
- parent->dv_xname, AcpiFormatException(rv));
- goto out4;
+ if (bus_space_map(sc->sc_csr_st, cmd_reg, 1, 0, &sc->sc_csr_sh) != 0) {
+ aprint_error_dev(self, "unable to map CSR register\n");
+ goto post_data_map;
}
- rv = AcpiEnableGpe(NULL, ecdt_sc->sc_gpebit, ACPI_NOT_ISR);
- if (ACPI_FAILURE(rv)) {
- printf("%s: unable to enable GPE: %s\n",
- parent->dv_xname, AcpiFormatException(rv));
- goto out4;
+ rv = acpi_eval_integer(sc->sc_ech, "_GLK", &val);
+ if (rv == AE_OK) {
+ sc->sc_need_global_lock = val != 0;
+ } else if (rv != AE_NOT_FOUND) {
+ aprint_error_dev(self, "unable to evaluate _GLK: %s\n",
+ AcpiFormatException(rv));
+ goto post_csr_map;
+ } else {
+ sc->sc_need_global_lock = false;
}
+ if (sc->sc_need_global_lock)
+ aprint_normal_dev(self, "using global ACPI lock\n");
- rv = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
- ACPI_ADR_SPACE_EC, EcSpaceHandler, EcSpaceSetup, ecdt_sc);
- if (ACPI_FAILURE(rv)) {
- printf("%s: unable to install address space handler: %s\n",
- parent->dv_xname,
+ rv = AcpiInstallAddressSpaceHandler(sc->sc_ech, ACPI_ADR_SPACE_EC,
+ acpiec_space_handler, acpiec_space_setup, self);
+ if (rv != AE_OK) {
+ aprint_error_dev(self,
+ "unable to install address space handler: %s\n",
AcpiFormatException(rv));
- goto out4;
+ goto post_csr_map;
}
- printf("%s: found ECDT, GPE %d\n", parent->dv_xname,
- ecdt_sc->sc_gpebit);
+ rv = AcpiInstallGpeHandler(sc->sc_gpeh, sc->sc_gpebit,
+ ACPI_GPE_EDGE_TRIGGERED, acpiec_gpe_handler, self);
+ if (rv != AE_OK) {
+ aprint_error_dev(self, "unable to install GPE handler: %s\n",
+ AcpiFormatException(rv));
+ goto post_csr_map;
+ }
- mutex_init(&ecdt_sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
- simple_lock_init(&ecdt_sc->sc_slock);
+ rv = AcpiSetGpeType(sc->sc_gpeh, sc->sc_gpebit, ACPI_GPE_TYPE_RUNTIME);
+ if (rv != AE_OK) {
+ aprint_error_dev(self, "unable to set GPE type: %s\n",
+ AcpiFormatException(rv));
+ goto post_csr_map;
+ }
- AcpiOsUnmapMemory(ep, ep->Length);
- return;
+ rv = AcpiEnableGpe(sc->sc_gpeh, sc->sc_gpebit, ACPI_ISR);
+ if (rv != AE_OK) {
+ aprint_error_dev(self, "unable to enable GPE: %s\n",
+ AcpiFormatException(rv));
+ goto post_csr_map;
+ }
- out4:
- AcpiRemoveGpeHandler(NULL, ecdt_sc->sc_gpebit, EcGpeHandler);
- out3:
- bus_space_unmap(ecdt_sc->sc_csr_st, ecdt_sc->sc_csr_sh, 1);
- out2:
- bus_space_unmap(ecdt_sc->sc_data_st, ecdt_sc->sc_data_sh, 1);
- out1:
- free(ecdt_sc, M_ACPI);
- ecdt_sc = NULL;
+ if (kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, acpiec_gpe_query,
+ self, NULL, "acpiec sci thread")) {
+ aprint_error_dev(self, "unable to create query kthread\n");
+ goto post_csr_map;
+ }
+
+ ec_singleton = self;
- AcpiOsUnmapMemory(ep, ep->Length);
+ if (!pmf_device_register(self, acpiec_suspend, acpiec_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
return;
+
+post_csr_map:
+ (void)AcpiRemoveGpeHandler(sc->sc_gpeh, sc->sc_gpebit,
+ acpiec_gpe_handler);
+ (void)AcpiRemoveAddressSpaceHandler(sc->sc_ech,
+ ACPI_ADR_SPACE_EC, acpiec_space_handler);
+ bus_space_unmap(sc->sc_csr_st, sc->sc_csr_sh, 1);
+post_data_map:
+ bus_space_unmap(sc->sc_data_st, sc->sc_data_sh, 1);
}
-/*
- * acpiec_attach:
- *
- * Autoconfiguration `attach' routine.
- */
-static void
-acpiec_attach(struct device *parent, struct device *self, void *aux)
+static bool
+acpiec_suspend(device_t dv)
{
- struct acpi_ec_softc *sc = (void *) self;
- struct acpi_attach_args *aa = aux;
- struct acpi_io *io0, *io1;
- struct acpi_resources res;
- ACPI_STATUS rv;
- ACPI_INTEGER v;
-
- ACPI_FUNCTION_TRACE(__FUNCTION__);
+ acpiec_cold = true;
- aprint_naive(": ACPI Embedded Controller\n");
- aprint_normal(": ACPI Embedded Controller\n");
-
- mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
- simple_lock_init(&sc->sc_slock);
-
- sc->sc_handle = aa->aa_node->ad_handle;
+ return true;
+}
- /* Parse our resources. */
- ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "parsing EC resources\n"));
- rv = acpi_resource_parse(&sc->sc_dev, sc->sc_handle, "_CRS",
- &res, &acpi_resource_parse_ops_default);
- if (ACPI_FAILURE(rv))
- return;
+static bool
+acpiec_resume(device_t dv)
+{
+ acpiec_cold = false;
-#define adi aa->aa_node->ad_devinfo
-
- /* check if we already attached EC via ECDT */
- if (ecdt_sc &&
- ((adi->Valid & ACPI_VALID_UID) == ACPI_VALID_UID) &&
- ecdt_sc->sc_uid == strtoul(adi->UniqueId.Value, NULL, 10)) {
- /* detach all ECDT handles */
- rv = AcpiRemoveAddressSpaceHandler(ACPI_ROOT_OBJECT,
- ACPI_ADR_SPACE_EC, EcSpaceHandler);
- if (ACPI_FAILURE(rv))
- aprint_error("ERROR: RemoveAddressSpaceHandler: %s\n",
- AcpiFormatException(rv));
- rv = AcpiRemoveGpeHandler(NULL, ecdt_sc->sc_gpebit,
- EcGpeHandler);
- if (ACPI_FAILURE(rv))
- aprint_error("ERROR: RemoveAddressSpaceHandler: %s\n",
- AcpiFormatException(rv));
+ return true;
+}
- bus_space_unmap(ecdt_sc->sc_csr_st,
- ecdt_sc->sc_csr_sh, 1);
- bus_space_unmap(ecdt_sc->sc_data_st,
- ecdt_sc->sc_data_sh, 1);
+static bool
+acpiec_parse_gpe_package(device_t self, ACPI_HANDLE ec_handle,
+ ACPI_HANDLE *gpe_handle, uint8_t *gpebit)
+{
+ ACPI_BUFFER buf;
+ ACPI_OBJECT *p, *c;
+ ACPI_STATUS rv;
- mutex_destroy(&ecdt_sc->sc_lock);
- free(ecdt_sc, M_ACPI);
- ecdt_sc = NULL;
+ rv = acpi_eval_struct(ec_handle, "_GPE", &buf);
+ if (rv != AE_OK) {
+ aprint_error_dev(self, "unable to evaluate _GPE: %s\n",
+ AcpiFormatException(rv));
+ return false;
}
-#undef adi
+ p = buf.Pointer;
- sc->sc_data_st = aa->aa_iot;
- io0 = acpi_res_io(&res, 0);
- if (io0 == NULL) {
- aprint_error("%s: unable to find data register resource\n",
- sc->sc_dev.dv_xname);
- goto out;
- }
- if (bus_space_map(sc->sc_data_st, io0->ar_base, io0->ar_length,
- 0, &sc->sc_data_sh) != 0) {
- aprint_error("%s: unable to map data register\n",
- sc->sc_dev.dv_xname);
- goto out;
+ if (p->Type == ACPI_TYPE_INTEGER) {
+ *gpe_handle = NULL;
+ *gpebit = p->Integer.Value;
+ AcpiOsFree(p);
+ return true;
}
- sc->sc_csr_st = aa->aa_iot;
- io1 = acpi_res_io(&res, 1);
- if (io1 == NULL) {
- aprint_error("%s: unable to find csr register resource\n",
- sc->sc_dev.dv_xname);
- goto out;
+ if (p->Type != ACPI_TYPE_PACKAGE) {
+ aprint_error_dev(self, "_GPE is neither integer nor package\n");
+ AcpiOsFree(p);
+ return false;
}
- if (bus_space_map(sc->sc_csr_st, io1->ar_base, io1->ar_length,
- 0, &sc->sc_csr_sh) != 0) {
- aprint_error("%s: unable to map csr register\n",
- sc->sc_dev.dv_xname);
- goto out;
+
+ if (p->Package.Count != 2) {
+ aprint_error_dev(self, "_GPE package does not contain 2 elements\n");
+ AcpiOsFree(p);
+ return false;
}
- /*
- * evaluate _GLK to see if we should acquire global lock
- * when accessing the EC.
- */
- rv = acpi_eval_integer(sc->sc_handle, "_GLK", &v);
- if (ACPI_FAILURE(rv)) {
- if (rv != AE_NOT_FOUND)
- aprint_error("%s: unable to evaluate _GLK: %s\n",
- sc->sc_dev.dv_xname,
- AcpiFormatException(rv));
- sc->sc_glk = 0;
- } else
- sc->sc_glk = v;
-
- /*
- * Install GPE handler.
- *
- * We evaluate the _GPE method to find the GPE bit used by the
- * Embedded Controller to signal status (SCI).
- */
- rv = acpi_eval_integer(sc->sc_handle, "_GPE", &v);
- if (ACPI_FAILURE(rv)) {
- aprint_error("%s: unable to evaluate _GPE: %s\n",
- sc->sc_dev.dv_xname, AcpiFormatException(rv));
- goto out;
- }
- sc->sc_gpebit = v;
+ c = &p->Package.Elements[0];
+ switch (c->Type) {
+ case ACPI_TYPE_LOCAL_REFERENCE:
+ case ACPI_TYPE_ANY:
+ *gpe_handle = c->Reference.Handle;
+ break;
+ case ACPI_TYPE_STRING:
+ /* XXX should be using real scope here */
+ rv = AcpiGetHandle(NULL, p->String.Pointer, gpe_handle);
+ if (rv != AE_OK) {
+ aprint_error_dev(self,
+ "_GPE device reference unresolvable\n");
+ AcpiOsFree(p);
+ return false;
+ }
+ break;
+ default:
+ aprint_error_dev(self, "_GPE device reference incorrect\n");
+ AcpiOsFree(p);
+ return false;
+ }
+ c = &p->Package.Elements[1];
+ if (c->Type != ACPI_TYPE_INTEGER) {
+ aprint_error_dev(self,
+ "_GPE package needs integer as 2nd field\n");
+ AcpiOsFree(p);
+ return false;
+ }
+ *gpebit = c->Integer.Value;
+ AcpiOsFree(p);
+ return true;
+}
- /*
- * Install a handler for this EC's GPE bit. Note that EC SCIs are
- * treated as both edge- and level-triggered interrupts; in other words
- * we clear the status bit immediately after getting an EC-SCI, then
- * again after we're done processing the event. This guarantees that
- * events we cause while performing a transaction (e.g. IBE/OBF) get
- * cleared before re-enabling the GPE.
- */
- rv = AcpiInstallGpeHandler(NULL, sc->sc_gpebit,
- ACPI_GPE_EDGE_TRIGGERED, EcGpeHandler, sc);
- if (ACPI_FAILURE(rv)) {
- aprint_error("%s: unable to install GPE handler: %s\n",
- sc->sc_dev.dv_xname, AcpiFormatException(rv));
- goto out;
- }
+static uint8_t
+acpiec_read_data(struct acpiec_softc *sc)
+{
+ return bus_space_read_1(sc->sc_data_st, sc->sc_data_sh, 0);
+}
- rv = AcpiSetGpeType(NULL, sc->sc_gpebit, ACPI_GPE_TYPE_RUNTIME);
- if (ACPI_FAILURE(rv)) {
- aprint_error("%s: unable to set GPE type: %s\n",
- sc->sc_dev.dv_xname, AcpiFormatException(rv));
- goto out2;
- }
+static void
+acpiec_write_data(struct acpiec_softc *sc, uint8_t val)
+{
+ bus_space_write_1(sc->sc_data_st, sc->sc_data_sh, 0, val);
+}
- rv = AcpiEnableGpe(NULL, sc->sc_gpebit, ACPI_NOT_ISR);
- if (ACPI_FAILURE(rv)) {
- aprint_error("%s: unable to enable GPE: %s\n",
- sc->sc_dev.dv_xname, AcpiFormatException(rv));
- goto out2;
- }
+static uint8_t
+acpiec_read_status(struct acpiec_softc *sc)
+{
+ return bus_space_read_1(sc->sc_csr_st, sc->sc_csr_sh, 0);
+}
- /* Install address space handler. */
- rv = AcpiInstallAddressSpaceHandler(sc->sc_handle,
- ACPI_ADR_SPACE_EC, EcSpaceHandler, EcSpaceSetup, sc);
- if (ACPI_FAILURE(rv)) {
- aprint_error("%s: unable to install address space handler: %s\n",
- sc->sc_dev.dv_xname, AcpiFormatException(rv));
- goto out2;
- }
+static void
+acpiec_write_command(struct acpiec_softc *sc, uint8_t cmd)
+{
+ bus_space_write_1(sc->sc_csr_st, sc->sc_csr_sh, 0, cmd);
+}
- return_VOID;
- out2:
- (void)AcpiRemoveGpeHandler(NULL, sc->sc_gpebit, EcGpeHandler);
+static ACPI_STATUS
+acpiec_space_setup(ACPI_HANDLE region, UINT32 func, void *arg,
+ void **region_arg)
+{
+ if (func == ACPI_REGION_DEACTIVATE)
+ *region_arg = NULL;
+ else
+ *region_arg = arg;
- out:
- acpi_resource_cleanup(&res);
- return_VOID;
+ return AE_OK;
}
static void
-EcGpeQueryHandler(void *Context)
+acpiec_lock(device_t dv)
{
- struct acpi_ec_softc *sc = Context;
- UINT8 Data = 0;
+ struct acpiec_softc *sc = device_private(dv);
ACPI_STATUS rv;
- char qxx[5];
- ACPI_FUNCTION_TRACE(__FUNCTION__);
-
- for (;;) {
- /*
- * Check EC_SCI.
- *
- * Bail out if the EC_SCI bit of the status register is not
- * set. Note that this function should only be called when
- * this bit is set (polling is used to detect IBE/OBF events).
- *
- * It is safe to do this without locking the controller, as
- * it's OK to call EcQuery when there's no data ready; in the
- * worst case we should just find nothing waiting for us and
- * bail.
- */
- if ((EC_CSR_READ(sc) & EC_EVENT_SCI) == 0)
- break;
-
- EcLock(sc);
-
- /*
- * Find out why the EC is signalling us
- */
- rv = EcQuery(sc, &Data);
-
- EcUnlock(sc);
-
- /*
- * If we failed to get anything from the EC, give up.
- */
- if (ACPI_FAILURE(rv)) {
- printf("%s: GPE query failed: %s\n",
- sc->sc_dev.dv_xname, AcpiFormatException(rv));
- break;
- }
+ mutex_enter(&sc->sc_access_mtx);
- /*
- * Evaluate _Qxx to respond to the controller.
- */
- snprintf(qxx, sizeof(qxx), "_Q%02X", Data);
- rv = AcpiEvaluateObject(sc->sc_handle, qxx,
- NULL, NULL);
-
- /*
- * Ignore spurious query requests.
- */
- if (ACPI_FAILURE(rv) &&
- (Data != 0 || rv != AE_NOT_FOUND)) {
- printf("%s: evaluation of GPE query method %s "
- "failed: %s\n", sc->sc_dev.dv_xname, qxx,
+ if (sc->sc_need_global_lock) {
+ rv = AcpiAcquireGlobalLock(EC_LOCK_TIMEOUT, &sc->sc_global_lock);
+ if (rv != AE_OK) {
+ aprint_error_dev(dv, "failed to acquire global lock: %s\n",
AcpiFormatException(rv));
+ return;
}
}
-
- /* I know I request Level trigger cleanup */
- rv = AcpiClearGpe(NULL, sc->sc_gpebit, ACPI_NOT_ISR);
- if (ACPI_FAILURE(rv))
- printf("%s: AcpiClearGpe failed: %s\n", sc->sc_dev.dv_xname,
- AcpiFormatException(rv));
-
- return_VOID;
}
-static UINT32
-EcGpeHandler(void *Context)
+static void
+acpiec_unlock(device_t dv)
{
- struct acpi_ec_softc *sc = Context;
- uint32_t csrvalue;
+ struct acpiec_softc *sc = device_private(dv);
ACPI_STATUS rv;
- /*
- * If EC is locked, the intr must process EcRead/Write wait only.
- * Query request must be pending.
- */
- simple_lock(&sc->sc_slock);
- if (sc->sc_flags & EC_F_TRANSACTION) {
- csrvalue = EC_CSR_READ(sc);
- sc->sc_flags |= EC_F_PENDQUERY;
-
- if ((csrvalue & EC_FLAG_OUTPUT_BUFFER) != 0 ||
- (csrvalue & EC_FLAG_INPUT_BUFFER) == 0) {
- sc->sc_csrvalue = csrvalue;
- wakeup(&sc->sc_csrvalue);
+ if (sc->sc_need_global_lock) {
+ rv = AcpiReleaseGlobalLock(sc->sc_global_lock);
+ if (rv != AE_OK) {
+ aprint_error_dev(dv, "failed to release global lock: %s\n",
+ AcpiFormatException(rv));
}
- simple_unlock(&sc->sc_slock);
- } else {
- simple_unlock(&sc->sc_slock);
- /* Enqueue GpeQuery handler. */
- rv = AcpiOsQueueForExecution(OSD_PRIORITY_HIGH,
- EcGpeQueryHandler, Context);
- if (ACPI_FAILURE(rv))
- printf("%s: failed to enqueue query handler: %s\n",
- sc->sc_dev.dv_xname, AcpiFormatException(rv));
+ }
+ mutex_exit(&sc->sc_access_mtx);
+}
+
+static ACPI_STATUS
+acpiec_read(device_t dv, uint8_t addr, uint8_t *val)
+{
+ struct acpiec_softc *sc = device_private(dv);
+ int i, timeouts = 0;
+
+ acpiec_lock(dv);
+ mutex_enter(&sc->sc_mtx);
+
+retry:
+ sc->sc_cur_addr = addr;
+ sc->sc_state = EC_STATE_READ;
+
+ for (i = 0; i < EC_POLL_TIMEOUT; ++i) {
+ acpiec_gpe_state_maschine(dv);
+ if (sc->sc_state == EC_STATE_FREE)
+ goto done;
+ delay(1);
}
- return 0; /* XXX not yet used in ACPI-CA */
+ if (cold || acpiec_cold) {
+ while (sc->sc_state != EC_STATE_FREE) {
+ delay(1);
+ acpiec_gpe_state_maschine(dv);
+ }
+ } else while (cv_timedwait(&sc->sc_cv, &sc->sc_mtx, hz)) {
+ mutex_exit(&sc->sc_mtx);
+ AcpiClearGpe(sc->sc_gpeh, sc->sc_gpebit, ACPI_NOT_ISR);
+ mutex_enter(&sc->sc_mtx);
+ if (++timeouts < 5)
+ goto retry;
+ mutex_exit(&sc->sc_mtx);
+ acpiec_unlock(dv);
+ aprint_error_dev(dv, "command takes over 5sec...\n");
+ return AE_ERROR;
+ }
+
+done:
+ *val = sc->sc_cur_val;
+
+ mutex_exit(&sc->sc_mtx);
+ acpiec_unlock(dv);
+ return AE_OK;
}
static ACPI_STATUS
-EcSpaceSetup(ACPI_HANDLE Region, UINT32 Function, void *Context,
- void **RegionContext)
+acpiec_write(device_t dv, uint8_t addr, uint8_t val)
{
+ struct acpiec_softc *sc = device_private(dv);
+ int i, timeouts = 0;
- ACPI_FUNCTION_TRACE(__FUNCTION__);
+ acpiec_lock(dv);
+ mutex_enter(&sc->sc_mtx);
- /*
- * Just pass the context through, there's nothing to do here.
- */
- if (Function == ACPI_REGION_DEACTIVATE)
- *RegionContext = NULL;
- else
- *RegionContext = Context;
+retry:
+ sc->sc_cur_addr = addr;
+ sc->sc_cur_val = val;
+ sc->sc_state = EC_STATE_WRITE;
- return_ACPI_STATUS(AE_OK);
+ for (i = 0; i < EC_POLL_TIMEOUT; ++i) {
+ acpiec_gpe_state_maschine(dv);
+ if (sc->sc_state == EC_STATE_FREE)
+ goto done;
+ delay(1);
+ }
+
+ if (cold || acpiec_cold) {
+ while (sc->sc_state != EC_STATE_FREE) {
+ delay(1);
+ acpiec_gpe_state_maschine(dv);
+ }
+ } else while (cv_timedwait(&sc->sc_cv, &sc->sc_mtx, hz)) {
+ mutex_exit(&sc->sc_mtx);
+ AcpiClearGpe(sc->sc_gpeh, sc->sc_gpebit, ACPI_NOT_ISR);
+ mutex_enter(&sc->sc_mtx);
+ if (++timeouts < 5)
+ goto retry;
+ mutex_exit(&sc->sc_mtx);
+ acpiec_unlock(dv);
+ aprint_error_dev(dv, "command takes over 5sec...\n");
+ return AE_ERROR;
+ }
+
+done:
+ mutex_exit(&sc->sc_mtx);
+ acpiec_unlock(dv);
+ return AE_OK;
}
static ACPI_STATUS
-EcSpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 width,
- ACPI_INTEGER *Value, void *Context, void *RegionContext)
+acpiec_space_handler(UINT32 func, ACPI_PHYSICAL_ADDRESS paddr,
+ UINT32 width, ACPI_INTEGER *value, void *arg, void *region_arg)
{
- struct acpi_ec_softc *sc = Context;
- ACPI_STATUS rv = AE_OK;
- EC_REQUEST EcRequest;
- int i;
+ device_t dv;
+ struct acpiec_softc *sc;
+ ACPI_STATUS rv;
+ uint8_t addr, reg;
+ unsigned int i;
- ACPI_FUNCTION_TRACE_U32(__FUNCTION__, (UINT32)Address);
+ if (paddr > 0xff || width % 8 != 0 || value == NULL || arg == NULL ||
+ paddr + width / 8 > 0xff)
+ return AE_BAD_PARAMETER;
- if ((Address > 0xFF) || (width % 8 != 0) || (Value == NULL) ||
- (Context == NULL))
- return_ACPI_STATUS(AE_BAD_PARAMETER);
+ addr = paddr;
+ dv = arg;
+ sc = device_private(dv);
- switch (Function) {
+ rv = AE_OK;
+
+ switch (func) {
case ACPI_READ:
- EcRequest.Command = EC_COMMAND_READ;
- EcRequest.Address = Address;
- (*Value) = 0;
+ *value = 0;
+ for (i = 0; i < width; i += 8, ++addr) {
+ rv = acpiec_read(dv, addr, &reg);
+ if (rv != AE_OK)
+ break;
+ *value |= (ACPI_INTEGER)reg << i;
+ }
break;
-
case ACPI_WRITE:
- EcRequest.Command = EC_COMMAND_WRITE;
- EcRequest.Address = Address;
+ for (i = 0; i < width; i += 8, ++addr) {
+ reg = (*value >>i) & 0xff;
+ rv = acpiec_write(dv, addr, reg);
+ if (rv != AE_OK)
+ break;
+ }
break;
-
default:
- printf("%s: invalid Address Space function: %d\n",
- sc->sc_dev.dv_xname, Function);
- return_ACPI_STATUS(AE_BAD_PARAMETER);
+ aprint_error("%s: invalid Address Space function called: %x\n",
+ device_xname(dv), (unsigned int)func);
+ return AE_BAD_PARAMETER;
}
- /*
- * Perform the transaction.
- */
- for (i = 0; i < width; i += 8) {
- if (Function == ACPI_READ)
- EcRequest.Data = 0;
- else
- EcRequest.Data = (UINT8)((*Value) >> i);
-
- rv = EcTransaction(sc, &EcRequest);
- if (ACPI_FAILURE(rv))
- break;
-
- (*Value) |= (UINT32)EcRequest.Data << i;
- if (++EcRequest.Address == 0)
- return_ACPI_STATUS(AE_BAD_PARAMETER);
- }
-
- return_ACPI_STATUS(rv);
+ return rv;
}
-static ACPI_STATUS
-EcWaitEventIntr(struct acpi_ec_softc *sc, EC_EVENT Event)
+static void
+acpiec_gpe_query(void *arg)
{
- EC_STATUS EcStatus;
+ device_t dv = arg;
+ struct acpiec_softc *sc = device_private(dv);
+ uint8_t reg;
+ char qxx[5];
+ ACPI_STATUS rv;
int i;
- ACPI_FUNCTION_TRACE_U32(__FUNCTION__, (UINT32)Event);
-
- /* XXX Need better test for "yes, you have interrupts". */
- if (cold)
- return_ACPI_STATUS(EcWaitEvent(sc, Event));
+loop:
+ mutex_enter(&sc->sc_mtx);
- if (EcIsLocked(sc) == 0)
- printf("%s: EcWaitEventIntr called without EC lock!\n",
- sc->sc_dev.dv_xname);
+ if (sc->sc_got_sci == false)
+ cv_wait(&sc->sc_cv_sci, &sc->sc_mtx);
+ mutex_exit(&sc->sc_mtx);
- EcStatus = EC_CSR_READ(sc);
+ acpiec_lock(dv);
+ mutex_enter(&sc->sc_mtx);
- /* Too long? */
- for (i = 0; i < 10; i++) {
- /* Check EC status against the desired event. */
- if ((Event == EC_EVENT_OUTPUT_BUFFER_FULL) &&
- (EcStatus & EC_FLAG_OUTPUT_BUFFER) != 0)
- return_ACPI_STATUS(AE_OK);
+ /* The Query command can always be issued, so be defensive here. */
+ sc->sc_got_sci = false;
+ sc->sc_state = EC_STATE_QUERY;
- if ((Event == EC_EVENT_INPUT_BUFFER_EMPTY) &&
- (EcStatus & EC_FLAG_INPUT_BUFFER) == 0)
- return_ACPI_STATUS(AE_OK);
-
- sc->sc_csrvalue = 0;
- /* XXXJRT Sleeping with a lock held? */
- if (tsleep(&sc->sc_csrvalue, 0, "EcWait", (hz + 99) / 100)
- != EWOULDBLOCK)
- EcStatus = sc->sc_csrvalue;
- else
- EcStatus = EC_CSR_READ(sc);
+ for (i = 0; i < EC_POLL_TIMEOUT; ++i) {
+ acpiec_gpe_state_maschine(dv);
+ if (sc->sc_state == EC_STATE_FREE)
+ goto done;
+ delay(1);
}
- return_ACPI_STATUS(AE_ERROR);
-}
-static ACPI_STATUS
-EcWaitEvent(struct acpi_ec_softc *sc, EC_EVENT Event)
-{
- EC_STATUS EcStatus;
- UINT32 i = 0;
+ cv_wait(&sc->sc_cv, &sc->sc_mtx);
- if (EcIsLocked(sc) == 0)
- printf("%s: EcWaitEvent called without EC lock!\n",
- sc->sc_dev.dv_xname);
+done:
+ reg = sc->sc_cur_val;
- /*
- * Stall 10us:
- * ----------
- * Stall for 10 microseconds before reading the status register
- * for the first time. This allows the EC to set the IBF/OBF
- * bit to its proper state.
- */
- AcpiOsStall(10);
+ mutex_exit(&sc->sc_mtx);
+ acpiec_unlock(dv);
+
+ if (reg == 0)
+ goto loop; /* Spurious query result */
/*
- * Wait For Event:
- * ---------------
- * Poll the EC status register to detect completion of the last
- * command. Wait up to 100ms (in 100us chunks) for this to occur.
+ * Evaluate _Qxx to respond to the controller.
*/
- for (i = 0; i < 1000; i++) {
- EcStatus = EC_CSR_READ(sc);
-
- if ((Event == EC_EVENT_OUTPUT_BUFFER_FULL) &&
- (EcStatus & EC_FLAG_OUTPUT_BUFFER) != 0)
- return AE_OK;
-
- if ((Event == EC_EVENT_INPUT_BUFFER_EMPTY) &&
- (EcStatus & EC_FLAG_INPUT_BUFFER) == 0)
- return AE_OK;
-
- AcpiOsStall(10);
+ snprintf(qxx, sizeof(qxx), "_Q%02X", (unsigned int)reg);
+ rv = AcpiEvaluateObject(sc->sc_ech, qxx, NULL, NULL);
+ if (rv != AE_OK && rv != AE_NOT_FOUND) {
+ aprint_error("%s: GPE query method %s failed: %s",
+ device_xname(dv), qxx, AcpiFormatException(rv));
}
- return AE_ERROR;
+ goto loop;
}
-static ACPI_STATUS
-EcQuery(struct acpi_ec_softc *sc, UINT8 *Data)
+static void
+acpiec_gpe_state_maschine(device_t dv)
{
- ACPI_STATUS rv;
+ struct acpiec_softc *sc = device_private(dv);
+ uint8_t reg;
- if (EcIsLocked(sc) == 0)
- printf("%s: EcQuery called without EC lock!\n",
- sc->sc_dev.dv_xname);
+ reg = acpiec_read_status(sc);
- EC_CSR_WRITE(sc, EC_COMMAND_QUERY);
- rv = EcWaitEventIntr(sc, EC_EVENT_OUTPUT_BUFFER_FULL);
- if (ACPI_SUCCESS(rv))
- *Data = EC_DATA_READ(sc);
+ if (reg & EC_STATUS_SCI)
+ sc->sc_got_sci = true;
- if (ACPI_FAILURE(rv))
- printf("%s: timed out waiting for EC to respond to "
- "EC_COMMAND_QUERY\n", sc->sc_dev.dv_xname);
-
- return rv;
-}
+ switch (sc->sc_state) {
+ case EC_STATE_QUERY:
+ if ((reg & EC_STATUS_IBF) != 0)
+ break; /* Nothing of interest here. */
+ acpiec_write_command(sc, EC_COMMAND_QUERY);
+ sc->sc_state = EC_STATE_QUERY_VAL;
+ break;
-static ACPI_STATUS
-EcTransaction(struct acpi_ec_softc *sc, EC_REQUEST *EcRequest)
-{
- ACPI_STATUS rv;
+ case EC_STATE_QUERY_VAL:
+ if ((reg & EC_STATUS_OBF) == 0)
+ break; /* Nothing of interest here. */
- EcLock(sc);
+ sc->sc_cur_val = acpiec_read_data(sc);
+ sc->sc_state = EC_STATE_FREE;
- /*
- * Perform the transaction, and make sure GPE is enabled before
- * doing so.
- */
- rv = AcpiEnableGpe(NULL, sc->sc_gpebit, ACPI_NOT_ISR);
- if (ACPI_FAILURE(rv))
- return rv;
- switch (EcRequest->Command) {
- case EC_COMMAND_READ:
- rv = EcRead(sc, EcRequest->Address, &(EcRequest->Data));
+ cv_signal(&sc->sc_cv);
break;
- case EC_COMMAND_WRITE:
- rv = EcWrite(sc, EcRequest->Address, &(EcRequest->Data));
- break;
+ case EC_STATE_READ:
+ if ((reg & EC_STATUS_IBF) != 0)
+ break; /* Nothing of interest here. */
- default:
- rv = AE_SUPPORT;
+ acpiec_write_command(sc, EC_COMMAND_READ);
+ sc->sc_state = EC_STATE_READ_ADDR;
break;
- }
- EcUnlock(sc);
+ case EC_STATE_READ_ADDR:
+ if ((reg & EC_STATUS_IBF) != 0)
+ break; /* Nothing of interest here. */
- return rv;
-}
+ acpiec_write_data(sc, sc->sc_cur_addr);
+ sc->sc_state = EC_STATE_READ_VAL;
+ break;
-static ACPI_STATUS
-EcRead(struct acpi_ec_softc *sc, UINT8 Address, UINT8 *Data)
-{
- ACPI_STATUS rv;
+ case EC_STATE_READ_VAL:
+ if ((reg & EC_STATUS_OBF) == 0)
+ break; /* Nothing of interest here. */
+ sc->sc_cur_val = acpiec_read_data(sc);
+ sc->sc_state = EC_STATE_FREE;
- if (EcIsLocked(sc) == 0)
- printf("%s: EcRead called without EC lock!\n",
- sc->sc_dev.dv_xname);
+ cv_signal(&sc->sc_cv);
+ break;
- /* EcBurstEnable(EmbeddedController); */
+ case EC_STATE_WRITE:
+ if ((reg & EC_STATUS_IBF) != 0)
+ break; /* Nothing of interest here. */
- EC_CSR_WRITE(sc, EC_COMMAND_READ);
- if ((rv = EcWaitEventIntr(sc, EC_EVENT_INPUT_BUFFER_EMPTY)) !=
- AE_OK) {
- printf("%s: EcRead: timeout waiting for EC to process "
- "read command\n", sc->sc_dev.dv_xname);
- return rv;
- }
+ acpiec_write_command(sc, EC_COMMAND_WRITE);
+ sc->sc_state = EC_STATE_WRITE_ADDR;
+ break;
- EC_DATA_WRITE(sc, Address);
- if ((rv = EcWaitEventIntr(sc, EC_EVENT_OUTPUT_BUFFER_FULL)) !=
- AE_OK) {
- printf("%s: EcRead: timeout waiting for EC to send data\n",
- sc->sc_dev.dv_xname);
- return rv;
- }
+ case EC_STATE_WRITE_ADDR:
+ if ((reg & EC_STATUS_IBF) != 0)
+ break; /* Nothing of interest here. */
+ acpiec_write_data(sc, sc->sc_cur_addr);
+ sc->sc_state = EC_STATE_WRITE_VAL;
+ break;
- (*Data) = EC_DATA_READ(sc);
+ case EC_STATE_WRITE_VAL:
+ if ((reg & EC_STATUS_IBF) != 0)
+ break; /* Nothing of interest here. */
+ sc->sc_state = EC_STATE_FREE;
+ cv_signal(&sc->sc_cv);
- /* EcBurstDisable(EmbeddedController); */
+ acpiec_write_data(sc, sc->sc_cur_val);
+ break;
- return AE_OK;
+ case EC_STATE_FREE:
+ if (sc->sc_got_sci)
+ cv_signal(&sc->sc_cv_sci);
+ break;
+ default:
+ panic("invalid state");
+ }
}
-static ACPI_STATUS
-EcWrite(struct acpi_ec_softc *sc, UINT8 Address, UINT8 *Data)
+static UINT32
+acpiec_gpe_handler(void *arg)
{
- ACPI_STATUS rv;
+ device_t dv = arg;
+ struct acpiec_softc *sc = device_private(dv);
- if (EcIsLocked(sc) == 0)
- printf("%s: EcWrite called without EC lock!\n",
- sc->sc_dev.dv_xname);
+ AcpiClearGpe(sc->sc_gpeh, sc->sc_gpebit, ACPI_ISR);
- /* EcBurstEnable(EmbeddedController); */
+ mutex_enter(&sc->sc_mtx);
+ acpiec_gpe_state_maschine(dv);
+ mutex_exit(&sc->sc_mtx);
- EC_CSR_WRITE(sc, EC_COMMAND_WRITE);
- if ((rv = EcWaitEventIntr(sc, EC_EVENT_INPUT_BUFFER_EMPTY)) !=
- AE_OK) {
- printf("%s: EcWrite: timeout waiting for EC to process "
- "write command\n", sc->sc_dev.dv_xname);
- return rv;
- }
-
- EC_DATA_WRITE(sc, Address);
- if ((rv = EcWaitEventIntr(sc, EC_EVENT_INPUT_BUFFER_EMPTY)) !=
- AE_OK) {
- printf("%s: EcWrite: timeout waiting for EC to process "
- "address\n", sc->sc_dev.dv_xname);
- return rv;
- }
-
- EC_DATA_WRITE(sc, *Data);
- if ((rv = EcWaitEventIntr(sc, EC_EVENT_INPUT_BUFFER_EMPTY)) !=
- AE_OK) {
- printf("%s: EcWrite: timeout waiting for EC to process "
- "data\n", sc->sc_dev.dv_xname);
- return rv;
- }
-
- /* EcBurstDisable(EmbeddedController); */
-
- return AE_OK;
+ return 0;
}
diff --git a/sys/dev/acpi/acpi_ecreg.h b/sys/dev/acpi/acpi_ecreg.h
index 3562febf905..e69de29bb2d 100644
--- a/sys/dev/acpi/acpi_ecreg.h
+++ b/sys/dev/acpi/acpi_ecreg.h
@@ -1,161 +0,0 @@
-/* $NetBSD: acpi_ecreg.h,v 1.3 2005/12/11 12:21:01 christos Exp $ */
-
-/******************************************************************************
- *
- * 1. Copyright Notice
- *
- * Some or all of this work - Copyright (c) 1999, Intel Corp. All rights
- * reserved.
- *
- * 2. License
- *
- * 2.1. This is your license from Intel Corp. under its intellectual property
- * rights. You may have additional license terms from the party that provided
- * you this software, covering your right to use that party's intellectual
- * property rights.
- *
- * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
- * copy of the source code appearing in this file ("Covered Code") an
- * irrevocable, perpetual, worldwide license under Intel's copyrights in the
- * base code distributed originally by Intel ("Original Intel Code") to copy,
- * make derivatives, distribute, use and display any portion of the Covered
- * Code in any form, with the right to sublicense such rights; and
- *
- * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
- * license (with the right to sublicense), under only those claims of Intel
- * patents that are infringed by the Original Intel Code, to make, use, sell,
- * offer to sell, and import the Covered Code and derivative works thereof
- * solely to the minimum extent necessary to exercise the above copyright
- * license, and in no event shall the patent license extend to any additions
- * to or modifications of the Original Intel Code. No other license or right
- * is granted directly or by implication, estoppel or otherwise;
- *
- * The above copyright and patent license is granted only if the following
- * conditions are met:
- *
- * 3. Conditions
- *
- * 3.1. Redistribution of Source with Rights to Further Distribute Source.
- * Redistribution of source code of any substantial portion of the Covered
- * Code or modification with rights to further distribute source must include
- * the above Copyright Notice, the above License, this list of Conditions,
- * and the following Disclaimer and Export Compliance provision. In addition,
- * Licensee must cause all Covered Code to which Licensee contributes to
- * contain a file documenting the changes Licensee made to create that Covered
- * Code and the date of any change. Licensee must include in that file the
- * documentation of any changes made by any predecessor Licensee. Licensee
- * must include a prominent statement that the modification is derived,
- * directly or indirectly, from Original Intel Code.
- *
- * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
- * Redistribution of source code of any substantial portion of the Covered
- * Code or modification without rights to further distribute source must
- * include the following Disclaimer and Export Compliance provision in the
- * documentation and/or other materials provided with distribution. In
- * addition, Licensee may not authorize further sublicense of source of any
- * portion of the Covered Code, and must include terms to the effect that the
- * license from Licensee to its licensee is limited to the intellectual
- * property embodied in the software Licensee provides to its licensee, and
- * not to intellectual property embodied in modifications its licensee may
- * make.
- *
- * 3.3. Redistribution of Executable. Redistribution in executable form of any
- * substantial portion of the Covered Code or modification must reproduce the
- * above Copyright Notice, and the following Disclaimer and Export Compliance
- * provision in the documentation and/or other materials provided with the
- * distribution.
- *
- * 3.4. Intel retains all right, title, and interest in and to the Original
- * Intel Code.
- *
- * 3.5. Neither the name Intel nor any other trademark owned or controlled by
- * Intel shall be used in advertising or otherwise to promote the sale, use or
- * other dealings in products derived from or relating to the Covered Code
- * without prior written authorization from Intel.
- *
- * 4. Disclaimer and Export Compliance
- *
- * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
- * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
- * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
- * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
- * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
- * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
- * PARTICULAR PURPOSE.
- *
- * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
- * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
- * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
- * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
- * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
- * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
- * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
- * LIMITED REMEDY.
- *
- * 4.3. Licensee shall not export, either directly or indirectly, any of this
- * software or system incorporating such software without first obtaining any
- * required license or other approval from the U. S. Department of Commerce or
- * any other agency or department of the United States Government. In the
- * event Licensee exports any such software from the United States or
- * re-exports any such software from a foreign destination, Licensee shall
- * ensure that the distribution and export/re-export of the software is in
- * compliance with all laws, regulations, orders, or other restrictions of the
- * U.S. Export Administration Regulations. Licensee agrees that neither it nor
- * any of its subsidiaries will export/re-export any technical data, process,
- * software, or service, directly or indirectly, to any country for which the
- * United States government or any agency thereof requires an export license,
- * other governmental approval, or letter of assurance, without first obtaining
- * such license, approval or letter.
- *
- *****************************************************************************/
-
-/*
- * EC_COMMAND:
- * -----------
- */
-typedef UINT8 EC_COMMAND;
-
-#define EC_COMMAND_UNKNOWN ((EC_COMMAND) 0x00)
-#define EC_COMMAND_READ ((EC_COMMAND) 0x80)
-#define EC_COMMAND_WRITE ((EC_COMMAND) 0x81)
-#define EC_COMMAND_BURST_ENABLE ((EC_COMMAND) 0x82)
-#define EC_COMMAND_BURST_DISABLE ((EC_COMMAND) 0x83)
-#define EC_COMMAND_QUERY ((EC_COMMAND) 0x84)
-
-/*
- * EC_STATUS:
- * ----------
- * The encoding of the EC status register is illustrated below.
- * Note that a set bit (1) indicates the property is TRUE
- * (e.g. if bit 0 is set then the output buffer is full).
- * +-+-+-+-+-+-+-+-+
- * |7|6|5|4|3|2|1|0|
- * +-+-+-+-+-+-+-+-+
- * | | | | | | | |
- * | | | | | | | +- Output Buffer Full?
- * | | | | | | +--- Input Buffer Full?
- * | | | | | +----- <reserved>
- * | | | | +------- Data Register is Command Byte?
- * | | | +--------- Burst Mode Enabled?
- * | | +----------- SCI Event?
- * | +------------- SMI Event?
- * +--------------- <Reserved>
- *
- */
-typedef UINT8 EC_STATUS;
-
-#define EC_FLAG_OUTPUT_BUFFER ((EC_STATUS) 0x01)
-#define EC_FLAG_INPUT_BUFFER ((EC_STATUS) 0x02)
-#define EC_FLAG_BURST_MODE ((EC_STATUS) 0x10)
-#define EC_FLAG_SCI ((EC_STATUS) 0x20)
-
-/*
- * EC_EVENT:
- * ---------
- */
-typedef UINT8 EC_EVENT;
-
-#define EC_EVENT_UNKNOWN ((EC_EVENT) 0x00)
-#define EC_EVENT_OUTPUT_BUFFER_FULL ((EC_EVENT) 0x01)
-#define EC_EVENT_INPUT_BUFFER_EMPTY ((EC_EVENT) 0x02)
-#define EC_EVENT_SCI ((EC_EVENT) 0x20)
diff --git a/sys/dev/acpi/acpi_lid.c b/sys/dev/acpi/acpi_lid.c
index 447952bc966..805fe7eda6b 100644
--- a/sys/dev/acpi/acpi_lid.c
+++ b/sys/dev/acpi/acpi_lid.c
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_lid.c,v 1.21 2006/11/16 01:32:47 christos Exp $ */
+/* $NetBSD: acpi_lid.c,v 1.22 2007/12/09 20:27:53 jmcneill Exp $ */
/*
* Copyright 2001, 2003 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_lid.c,v 1.21 2006/11/16 01:32:47 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_lid.c,v 1.22 2007/12/09 20:27:53 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -72,6 +72,8 @@ CFATTACH_DECL(acpilid, sizeof(struct acpilid_softc),
static void acpilid_status_changed(void *);
static void acpilid_notify_handler(ACPI_HANDLE, UINT32, void *);
+static bool acpilid_suspend(device_t);
+
/*
* acpilid_match:
*
@@ -123,6 +125,30 @@ acpilid_attach(struct device *parent, struct device *self, void *aux)
}
acpi_set_wake_gpe(sc->sc_node->ad_handle);
+
+ if (!pmf_device_register(self, acpilid_suspend, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+}
+
+static void
+acpilid_wake_event(struct acpilid_softc *sc, bool enable)
+{
+ ACPI_STATUS rv;
+ ACPI_OBJECT_LIST ArgList;
+ ACPI_OBJECT Arg;
+
+ ArgList.Count = 1;
+ ArgList.Pointer = &Arg;
+
+ Arg.Type = ACPI_TYPE_INTEGER;
+ Arg.Integer.Value = enable ? 1 : 0;
+
+ rv = AcpiEvaluateObject (sc->sc_node->ad_handle, "_PSW",
+ &ArgList, NULL);
+ if (ACPI_FAILURE(rv) && rv != AE_NOT_FOUND)
+ aprint_error_dev(&sc->sc_dev,
+ "unable to evaluate _PSW handler: %s\n",
+ AcpiFormatException(rv));
}
/*
@@ -163,7 +189,7 @@ acpilid_notify_handler(ACPI_HANDLE handle, UINT32 notify,
printf("%s: received LidStatusChanged message\n",
sc->sc_dev.dv_xname);
#endif
- rv = AcpiOsQueueForExecution(OSD_PRIORITY_LO,
+ rv = AcpiOsExecute(OSL_NOTIFY_HANDLER,
acpilid_status_changed, sc);
if (ACPI_FAILURE(rv))
printf("%s: WARNING: unable to queue lid change "
@@ -176,3 +202,18 @@ acpilid_notify_handler(ACPI_HANDLE handle, UINT32 notify,
sc->sc_dev.dv_xname, notify);
}
}
+
+static bool
+acpilid_suspend(device_t dv)
+{
+ struct acpilid_softc *sc = device_private(dv);
+ ACPI_INTEGER status;
+ ACPI_STATUS rv;
+
+ rv = acpi_eval_integer(sc->sc_node->ad_handle, "_LID", &status);
+ if (ACPI_FAILURE(rv))
+ return true;
+
+ acpilid_wake_event(sc, status == 0);
+ return true;
+}
diff --git a/sys/dev/acpi/acpi_madt.c b/sys/dev/acpi/acpi_madt.c
index d3b553554dd..bc398e29672 100644
--- a/sys/dev/acpi/acpi_madt.c
+++ b/sys/dev/acpi/acpi_madt.c
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_madt.c,v 1.17 2006/11/16 01:32:47 christos Exp $ */
+/* $NetBSD: acpi_madt.c,v 1.18 2007/12/09 20:27:53 jmcneill Exp $ */
/*
* Copyright (c) 2003 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_madt.c,v 1.17 2006/11/16 01:32:47 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_madt.c,v 1.18 2007/12/09 20:27:53 jmcneill Exp $");
#include <sys/param.h>
#include <sys/ioctl.h>
@@ -74,8 +74,7 @@ acpi_madt_map(void)
if (madt_header != NULL)
return AE_ALREADY_EXISTS;
- rv = AcpiGetFirmwareTable(APIC_SIG, 1, ACPI_LOGICAL_ADDRESSING,
- &madt_header);
+ rv = AcpiGetTable(ACPI_SIG_MADT, 1, &madt_header);
if (ACPI_FAILURE(rv))
return rv;
@@ -90,7 +89,6 @@ acpi_madt_map(void)
void
acpi_madt_unmap(void)
{
- AcpiOsUnmapMemory(madt_header, madt_header->Length);
madt_header = NULL;
}
@@ -161,15 +159,15 @@ acpi_print_platint(MADT_INTERRUPT_SOURCE *p)
#endif
void
-acpi_madt_walk(ACPI_STATUS (*func)(APIC_HEADER *, void *), void *aux)
+acpi_madt_walk(ACPI_STATUS (*func)(ACPI_SUBTABLE_HEADER *, void *), void *aux)
{
char *madtend, *where;
- APIC_HEADER *hdrp;
+ ACPI_SUBTABLE_HEADER *hdrp;
madtend = (char *)madt_header + madt_header->Length;
- where = (char *)madt_header + sizeof (MULTIPLE_APIC_TABLE);
+ where = (char *)madt_header + sizeof (ACPI_TABLE_MADT);
while (where < madtend) {
- hdrp = (APIC_HEADER *)where;
+ hdrp = (ACPI_SUBTABLE_HEADER *)where;
if (ACPI_FAILURE(func(hdrp, aux)))
break;
where += hdrp->Length;
@@ -193,34 +191,34 @@ acpi_madt_print(void)
}
static ACPI_STATUS
-acpi_madt_print_entry(APIC_HEADER *hdrp, void *aux)
+acpi_madt_print_entry(ACPI_SUBTABLE_HEADER *hdrp, void *aux)
{
switch (hdrp->Type) {
- case APIC_PROCESSOR:
+ case ACPI_MADT_TYPE_LOCAL_APIC:
acpi_print_apic_proc((void *)hdrp);
break;
- case APIC_IO:
+ case ACPI_MADT_TYPE_IO_APIC:
acpi_print_ioapic((void *)hdrp);
break;
- case APIC_XRUPT_OVERRIDE:
+ case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
acpi_print_intsrc_ovr((void *)hdrp);
break;
- case APIC_NMI:
+ case ACPI_MADT_TYPE_NMI_SOURCE:
acpi_print_intsrc_nmi((void *)hdrp);
break;
- case APIC_LOCAL_NMI:
+ case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
acpi_print_lapic_nmi((void *)hdrp);
break;
- case APIC_ADDRESS_OVERRIDE:
+ case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
acpi_print_lapic_addr_ovr((void *)hdrp);
break;
- case APIC_IO_SAPIC:
+ case ACPI_MADT_TYPE_IO_SAPIC:
acpi_print_iosapic((void *)hdrp);
break;
- case APIC_LOCAL_SAPIC:
+ case ACPI_MADT_TYPE_LOCAL_SAPIC:
acpi_print_local_sapic((void *)hdrp);
break;
- case APIC_XRUPT_SOURCE:
+ case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
acpi_print_platint((void *)hdrp);
break;
default:
diff --git a/sys/dev/acpi/acpi_madt.h b/sys/dev/acpi/acpi_madt.h
index 5702e76b0d8..f8588316e53 100644
--- a/sys/dev/acpi/acpi_madt.h
+++ b/sys/dev/acpi/acpi_madt.h
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_madt.h,v 1.6 2005/12/11 12:21:01 christos Exp $ */
+/* $NetBSD: acpi_madt.h,v 1.7 2007/12/09 20:27:53 jmcneill Exp $ */
/*
* Copyright (c) 2003 Wasabi Systems, Inc.
@@ -41,4 +41,4 @@
ACPI_STATUS acpi_madt_map(void);
void acpi_madt_unmap(void);
-void acpi_madt_walk(ACPI_STATUS (*)(APIC_HEADER *, void *), void *);
+void acpi_madt_walk(ACPI_STATUS (*)(ACPI_SUBTABLE_HEADER *, void *), void *);
diff --git a/sys/dev/acpi/acpi_pci_link.c b/sys/dev/acpi/acpi_pci_link.c
index 15e48da0883..5d117c0cf2a 100644
--- a/sys/dev/acpi/acpi_pci_link.c
+++ b/sys/dev/acpi/acpi_pci_link.c
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_pci_link.c,v 1.9 2007/11/07 15:29:15 joerg Exp $ */
+/* $NetBSD: acpi_pci_link.c,v 1.10 2007/12/09 20:27:53 jmcneill Exp $ */
/*-
* Copyright (c) 2002 Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_pci_link.c,v 1.9 2007/11/07 15:29:15 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_pci_link.c,v 1.10 2007/12/09 20:27:53 jmcneill Exp $");
#include "opt_acpi.h"
#include <sys/param.h>
@@ -384,7 +384,7 @@ link_valid_irq(struct link *link, int irq)
* For links routed via an ISA interrupt, if the SCI is routed via
* an ISA interrupt, the SCI is always treated as a valid IRQ.
*/
- if (link->l_isa_irq && AcpiGbl_FADT->SciInt == irq &&
+ if (link->l_isa_irq && AcpiGbl_FADT.SciInterrupt == irq &&
irq < NUM_ISA_INTERRUPTS)
return (TRUE);
@@ -1039,7 +1039,7 @@ acpi_pci_link_choose_irq(struct acpi_pci_link_softc *sc, struct link *link)
* interrupt as a fallback.
*/
if (link->l_isa_irq && !PCI_INTERRUPT_VALID(best_irq)) {
- pos_irq = AcpiGbl_FADT->SciInt;
+ pos_irq = AcpiGbl_FADT.SciInterrupt;
pos_weight = pci_link_interrupt_weights[pos_irq];
if (pos_weight < best_weight) {
best_weight = pos_weight;
@@ -1136,8 +1136,8 @@ acpi_pci_link_init(struct acpi_pci_link_softc *sc)
* if we are using the APIC, we also shouldn't be having any PCI
* interrupts routed via ISA IRQs, so this is probably ok.
*/
- if (AcpiGbl_FADT->SciInt < NUM_ISA_INTERRUPTS)
- pci_link_bios_isa_irqs |= (1 << AcpiGbl_FADT->SciInt);
+ if (AcpiGbl_FADT.SciInterrupt < NUM_ISA_INTERRUPTS)
+ pci_link_bios_isa_irqs |= (1 << AcpiGbl_FADT.SciInterrupt);
sc->pl_powerhook = powerhook_establish(acpipcilinkname,
acpi_pci_link_resume, sc);
diff --git a/sys/dev/acpi/acpi_quirks.c b/sys/dev/acpi/acpi_quirks.c
index 972463330bf..14acc6135ce 100644
--- a/sys/dev/acpi/acpi_quirks.c
+++ b/sys/dev/acpi/acpi_quirks.c
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_quirks.c,v 1.8 2006/09/23 17:04:26 fvdl Exp $ */
+/* $NetBSD: acpi_quirks.c,v 1.9 2007/12/09 20:27:53 jmcneill Exp $ */
/*
* Copyright 2002 Wasabi Systems, Inc.
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_quirks.c,v 1.8 2006/09/23 17:04:26 fvdl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_quirks.c,v 1.9 2007/12/09 20:27:53 jmcneill Exp $");
#include "opt_acpi.h"
@@ -58,9 +58,9 @@ static int acpi_rev_cmp(uint32_t, uint32_t, int);
* XXX add more
*/
static struct acpi_quirk acpi_quirks[] = {
- { ACPI_TABLE_FADT, "PTLTD ", 0x06040000, AQ_LTE, " FACP ",
+ { ACPI_SIG_FADT, "PTLTD ", 0x06040000, AQ_LTE, " FACP ",
ACPI_QUIRK_BROKEN },
- { ACPI_TABLE_FADT, "NVIDIA", 0x06040000, AQ_EQ, "CK8 ",
+ { ACPI_SIG_FADT, "NVIDIA", 0x06040000, AQ_EQ, "CK8 ",
ACPI_QUIRK_IRQ0 },
};
@@ -106,26 +106,27 @@ acpi_find_quirks(void)
{
int i, nquirks;
struct acpi_quirk *aqp;
- ACPI_TABLE_HEADER *hdr;
+ ACPI_TABLE_HEADER fadt, dsdt, xsdt, *hdr;
nquirks = sizeof(acpi_quirks) / sizeof(struct acpi_quirk);
+ if (ACPI_FAILURE(AcpiGetTableHeader(ACPI_SIG_FADT, 0, &fadt)))
+ memset(&fadt, 0, sizeof(fadt));
+ if (ACPI_FAILURE(AcpiGetTableHeader(ACPI_SIG_DSDT, 0, &dsdt)))
+ memset(&dsdt, 0, sizeof(dsdt));
+ if (ACPI_FAILURE(AcpiGetTableHeader(ACPI_SIG_XSDT, 0, &xsdt)))
+ memset(&xsdt, 0, sizeof(xsdt));
+
for (i = 0; i < nquirks; i++) {
aqp = &acpi_quirks[i];
- /* XXX AcpiGetTableHeader doesn't work for some reason */
- switch (aqp->aq_tabletype) {
- case ACPI_TABLE_DSDT:
- hdr = (ACPI_TABLE_HEADER *)AcpiGbl_DSDT;
- break;
- case ACPI_TABLE_XSDT:
- hdr = (ACPI_TABLE_HEADER *)AcpiGbl_XSDT;
- break;
- case ACPI_TABLE_FADT:
- hdr = (ACPI_TABLE_HEADER *)AcpiGbl_FADT;
- break;
- default:
+ if (!strncmp(aqp->aq_tabletype, ACPI_SIG_DSDT, 4))
+ hdr = &dsdt;
+ else if (!strncmp(aqp->aq_tabletype, ACPI_SIG_XSDT, 4))
+ hdr = &xsdt;
+ else if (!strncmp(aqp->aq_tabletype, ACPI_SIG_FADT, 4))
+ hdr = &fadt;
+ else
continue;
- }
if (strncmp(aqp->aq_oemid, hdr->OemId, strlen(aqp->aq_oemid)))
continue;
if (acpi_rev_cmp(aqp->aq_oemrev, hdr->OemRevision,
diff --git a/sys/dev/acpi/acpi_tz.c b/sys/dev/acpi/acpi_tz.c
index 53c00901617..2fc7e3fe24d 100644
--- a/sys/dev/acpi/acpi_tz.c
+++ b/sys/dev/acpi/acpi_tz.c
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_tz.c,v 1.31 2007/12/08 23:01:30 jmcneill Exp $ */
+/* $NetBSD: acpi_tz.c,v 1.32 2007/12/09 20:27:53 jmcneill Exp $ */
/*
* Copyright (c) 2003 Jared D. McNeill <jmcneill@invisible.ca>
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_tz.c,v 1.31 2007/12/08 23:01:30 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_tz.c,v 1.32 2007/12/09 20:27:53 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -200,6 +200,9 @@ acpitz_attach(struct device *parent, struct device *self, void *aux)
acpitz_init_envsys(sc);
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error(": couldn't establish power handler\n");
+
callout_schedule(&sc->sc_callout, sc->sc_zone.tzp * hz / 10);
}
@@ -523,7 +526,7 @@ acpitz_notify_handler(ACPI_HANDLE hdl, UINT32 notify, void *opaque)
KASSERT(func != NULL);
- rv = AcpiOsQueueForExecution(OSD_PRIORITY_LO, func, sc);
+ rv = AcpiOsExecute(OSL_NOTIFY_HANDLER, func, sc);
if (rv != AE_OK)
printf("%s: unable to queue %s\n", sc->sc_dev.dv_xname, name);
@@ -564,7 +567,7 @@ acpitz_tick(void *opaque)
{
struct acpitz_softc *sc = opaque;
- AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpitz_get_status, sc);
+ AcpiOsExecute(OSL_NOTIFY_HANDLER, acpitz_get_status, sc);
callout_schedule(&sc->sc_callout, sc->sc_zone.tzp * hz / 10);
}
diff --git a/sys/dev/acpi/acpica/OsdEnvironment.c b/sys/dev/acpi/acpica/OsdEnvironment.c
index 8bc26e81981..dca9b7a0ab5 100644
--- a/sys/dev/acpi/acpica/OsdEnvironment.c
+++ b/sys/dev/acpi/acpica/OsdEnvironment.c
@@ -1,4 +1,4 @@
-/* $NetBSD: OsdEnvironment.c,v 1.1 2006/03/23 13:41:13 kochi Exp $ */
+/* $NetBSD: OsdEnvironment.c,v 1.2 2007/12/09 20:27:53 jmcneill Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: OsdEnvironment.c,v 1.1 2006/03/23 13:41:13 kochi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: OsdEnvironment.c,v 1.2 2007/12/09 20:27:53 jmcneill Exp $");
#include <sys/types.h>
@@ -100,8 +100,8 @@ AcpiOsTerminate(void)
*
* Obtain the Root ACPI talbe pointer (RSDP)
*/
-ACPI_STATUS
-AcpiOsGetRootPointer(UINT32 Flags, ACPI_POINTER *PhysicalAddress)
+ACPI_PHYSICAL_ADDRESS
+AcpiOsGetRootPointer(void)
{
- return acpi_OsGetRootPointer(Flags, PhysicalAddress);
+ return acpi_OsGetRootPointer();
}
diff --git a/sys/dev/acpi/acpica/OsdHardware.c b/sys/dev/acpi/acpica/OsdHardware.c
index b9e369809ff..c2c7258205c 100644
--- a/sys/dev/acpi/acpica/OsdHardware.c
+++ b/sys/dev/acpi/acpica/OsdHardware.c
@@ -1,4 +1,4 @@
-/* $NetBSD: OsdHardware.c,v 1.2 2006/05/14 21:42:26 elad Exp $ */
+/* $NetBSD: OsdHardware.c,v 1.3 2007/12/09 20:27:54 jmcneill Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -44,7 +44,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: OsdHardware.c,v 1.2 2006/05/14 21:42:26 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: OsdHardware.c,v 1.3 2007/12/09 20:27:54 jmcneill Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -129,9 +129,9 @@ AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, UINT32 *Value, UINT32 Width)
void *LogicalAddress;
ACPI_STATUS rv;
- rv = AcpiOsMapMemory(Address, Width / 8, &LogicalAddress);
- if (rv != AE_OK)
- return rv;
+ LogicalAddress = AcpiOsMapMemory(Address, Width / 8);
+ if (LogicalAddress == NULL)
+ return AE_NOT_EXIST;
switch (Width) {
case 8:
@@ -166,9 +166,9 @@ AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT32 Value, UINT32 Width)
void *LogicalAddress;
ACPI_STATUS rv;
- rv = AcpiOsMapMemory(Address, Width / 8, &LogicalAddress);
- if (rv != AE_OK)
- return rv;
+ LogicalAddress = AcpiOsMapMemory(Address, Width / 8);
+ if (LogicalAddress == NULL)
+ return AE_NOT_FOUND;
switch (Width) {
case 8:
diff --git a/sys/dev/acpi/acpica/OsdMemory.c b/sys/dev/acpi/acpica/OsdMemory.c
index 718983fa97c..326a0496ce0 100644
--- a/sys/dev/acpi/acpica/OsdMemory.c
+++ b/sys/dev/acpi/acpica/OsdMemory.c
@@ -1,4 +1,4 @@
-/* $NetBSD: OsdMemory.c,v 1.1 2006/03/23 13:41:13 kochi Exp $ */
+/* $NetBSD: OsdMemory.c,v 1.2 2007/12/09 20:27:54 jmcneill Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: OsdMemory.c,v 1.1 2006/03/23 13:41:13 kochi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: OsdMemory.c,v 1.2 2007/12/09 20:27:54 jmcneill Exp $");
#include <sys/param.h>
#include <sys/malloc.h>
@@ -58,12 +58,16 @@ MALLOC_DECLARE(M_ACPI);
*
* Map physical memory into the caller's address space.
*/
-ACPI_STATUS
-AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS PhysicalAddress, ACPI_SIZE Length,
- void **LogicalAddress)
+void *
+AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS PhysicalAddress, ACPI_SIZE Length)
{
+ ACPI_STATUS Status;
+ void *LogicalAddress = NULL;
- return acpi_md_OsMapMemory(PhysicalAddress, Length, LogicalAddress);
+ Status = acpi_md_OsMapMemory(PhysicalAddress, Length, &LogicalAddress);
+ if (ACPI_FAILURE (Status))
+ return NULL;
+ return LogicalAddress;
}
/*
@@ -139,3 +143,18 @@ AcpiOsWritable(void *Pointer, ACPI_SIZE Length)
return acpi_md_OsWritable(Pointer, Length);
}
+
+ACPI_STATUS
+AcpiOsValidateInterface(char *Interface)
+{
+
+ return AE_SUPPORT;
+}
+
+ACPI_STATUS
+AcpiOsValidateAddress(UINT8 SpaceId, ACPI_PHYSICAL_ADDRESS Address,
+ ACPI_SIZE Length)
+{
+
+ return AE_OK;
+}
diff --git a/sys/dev/acpi/acpica/OsdSchedule.c b/sys/dev/acpi/acpica/OsdSchedule.c
index a75b5f47f31..62a912f3519 100644
--- a/sys/dev/acpi/acpica/OsdSchedule.c
+++ b/sys/dev/acpi/acpica/OsdSchedule.c
@@ -1,4 +1,4 @@
-/* $NetBSD: OsdSchedule.c,v 1.1 2006/03/23 13:41:13 kochi Exp $ */
+/* $NetBSD: OsdSchedule.c,v 1.2 2007/12/09 20:27:54 jmcneill Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: OsdSchedule.c,v 1.1 2006/03/23 13:41:13 kochi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: OsdSchedule.c,v 1.2 2007/12/09 20:27:54 jmcneill Exp $");
#include <sys/param.h>
#include <sys/malloc.h>
@@ -96,7 +96,7 @@ acpi_osd_sched_fini(void)
*
* Obtain the ID of the currently executing thread.
*/
-UINT32
+ACPI_THREAD_ID
AcpiOsGetThreadId(void)
{
@@ -114,30 +114,28 @@ AcpiOsGetThreadId(void)
* Schedule a procedure for deferred execution.
*/
ACPI_STATUS
-AcpiOsQueueForExecution(UINT32 Priority, ACPI_OSD_EXEC_CALLBACK Function,
+AcpiOsExecute(ACPI_EXECUTE_TYPE Type, ACPI_OSD_EXEC_CALLBACK Function,
void *Context)
{
int pri;
ACPI_FUNCTION_TRACE(__FUNCTION__);
- switch (Priority) {
- case OSD_PRIORITY_GPE:
- pri = 3;
+ switch (Type) {
+ case OSL_GPE_HANDLER:
+ pri = 10;
break;
-
- case OSD_PRIORITY_HIGH:
- pri = 2;
+ case OSL_GLOBAL_LOCK_HANDLER:
+ case OSL_EC_POLL_HANDLER:
+ case OSL_EC_BURST_HANDLER:
+ pri = 5;
break;
-
- case OSD_PRIORITY_MED:
- pri = 1;
+ case OSL_NOTIFY_HANDLER:
+ pri = 3;
break;
-
- case OSD_PRIORITY_LO:
+ case OSL_DEBUGGER_THREAD:
pri = 0;
break;
-
default:
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
diff --git a/sys/dev/acpi/acpica/OsdSynch.c b/sys/dev/acpi/acpica/OsdSynch.c
index 5ea8c88f502..2819c1980c8 100644
--- a/sys/dev/acpi/acpica/OsdSynch.c
+++ b/sys/dev/acpi/acpica/OsdSynch.c
@@ -1,4 +1,4 @@
-/* $NetBSD: OsdSynch.c,v 1.8 2007/12/05 07:06:51 ad Exp $ */
+/* $NetBSD: OsdSynch.c,v 1.9 2007/12/09 20:27:54 jmcneill Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -69,7 +69,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: OsdSynch.c,v 1.8 2007/12/05 07:06:51 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: OsdSynch.c,v 1.9 2007/12/09 20:27:54 jmcneill Exp $");
#include <sys/param.h>
#include <sys/malloc.h>
@@ -165,7 +165,7 @@ AcpiOsDeleteSemaphore(ACPI_HANDLE Handle)
* Wait for units from a semaphore.
*/
ACPI_STATUS
-AcpiOsWaitSemaphore(ACPI_HANDLE Handle, UINT32 Units, UINT16 Timeout)
+AcpiOsWaitSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units, UINT16 Timeout)
{
struct acpi_semaphore *as = (void *) Handle;
ACPI_STATUS rv;
@@ -181,6 +181,8 @@ AcpiOsWaitSemaphore(ACPI_HANDLE Handle, UINT32 Units, UINT16 Timeout)
if (as == NULL)
return_ACPI_STATUS(AE_BAD_PARAMETER);
+ if (cold)
+ return_ACPI_STATUS(AE_OK);
/* A timeout of 0xFFFF means "forever". */
if (Timeout == 0xFFFF)
@@ -285,7 +287,7 @@ AcpiOsCreateLock(ACPI_HANDLE *OutHandle)
* Delete a lock.
*/
void
-AcpiOsDeleteLock(ACPI_HANDLE Handle)
+AcpiOsDeleteLock(ACPI_SPINLOCK Handle)
{
struct acpi_lock *al = (void *) Handle;
@@ -308,7 +310,7 @@ AcpiOsDeleteLock(ACPI_HANDLE Handle)
* Acquire a lock.
*/
ACPI_NATIVE_UINT
-AcpiOsAcquireLock(ACPI_HANDLE Handle)
+AcpiOsAcquireLock(ACPI_SPINLOCK Handle)
{
struct acpi_lock *al = (void *) Handle;
diff --git a/sys/dev/acpi/acpica/files.acpica b/sys/dev/acpi/acpica/files.acpica
index 95c58e830e5..2e178ad153c 100644
--- a/sys/dev/acpi/acpica/files.acpica
+++ b/sys/dev/acpi/acpica/files.acpica
@@ -1,4 +1,4 @@
-# $NetBSD: files.acpica,v 1.12 2006/03/23 13:44:10 kochi Exp $
+# $NetBSD: files.acpica,v 1.13 2007/12/09 20:27:54 jmcneill Exp $
file dev/acpi/acpica/OsdEnvironment.c acpi
file dev/acpi/acpica/OsdHardware.c acpi
@@ -132,11 +132,9 @@ file dist/acpica/rsutils.c acpi
file dist/acpica/rsxface.c acpi
# tables/
-file dist/acpica/tbconvrt.c acpi
-file dist/acpica/tbget.c acpi
-file dist/acpica/tbgetall.c acpi
+file dist/acpica/tbfadt.c acpi
+file dist/acpica/tbfind.c acpi
file dist/acpica/tbinstal.c acpi
-file dist/acpica/tbrsdt.c acpi
file dist/acpica/tbutils.c acpi
file dist/acpica/tbxface.c acpi
file dist/acpica/tbxfroot.c acpi
@@ -156,5 +154,6 @@ file dist/acpica/utmutex.c acpi
file dist/acpica/utobject.c acpi
file dist/acpica/utresrc.c acpi
file dist/acpica/utstate.c acpi
+file dist/acpica/uttrack.c acpi
file dist/acpica/utxface.c acpi
diff --git a/sys/dev/acpi/acpivar.h b/sys/dev/acpi/acpivar.h
index 67a5fb97815..4a6f289c646 100644
--- a/sys/dev/acpi/acpivar.h
+++ b/sys/dev/acpi/acpivar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: acpivar.h,v 1.30 2007/10/19 11:59:35 ad Exp $ */
+/* $NetBSD: acpivar.h,v 1.31 2007/12/09 20:27:53 jmcneill Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -260,7 +260,7 @@ extern const struct acpi_resource_parse_ops acpi_resource_parse_ops_default;
int acpi_check(device_t, const char *);
int acpi_probe(void);
-ACPI_STATUS acpi_OsGetRootPointer(UINT32, ACPI_POINTER *);
+ACPI_PHYSICAL_ADDRESS acpi_OsGetRootPointer(void);
int acpi_match_hid(ACPI_DEVICE_INFO *, const char * const *);
void acpi_set_wake_gpe(ACPI_HANDLE);
@@ -289,19 +289,6 @@ char * acpi_pci_link_name(void *);
ACPI_HANDLE acpi_pci_link_handle(void *);
void acpi_pci_link_state(void);
-
-
-
-#if defined(_KERNEL_OPT)
-#include "acpiec.h"
-
-#if NACPIEC > 0
-void acpiec_early_attach(struct device *);
-#endif
-#else
-#define NACPIEC 0
-#endif
-
struct acpi_io *acpi_res_io(struct acpi_resources *, int);
struct acpi_iorange *acpi_res_iorange(struct acpi_resources *, int);
struct acpi_mem *acpi_res_mem(struct acpi_resources *, int);
@@ -318,7 +305,7 @@ ACPI_STATUS acpi_enter_sleep_state(struct acpi_softc *, int);
* quirk handling
*/
struct acpi_quirk {
- uint32_t aq_tabletype; /* what type of table (FADT, DSDT, etc) */
+ const char *aq_tabletype; /* what type of table (FADT, DSDT, etc) */
const char *aq_oemid; /* compared against the table OemId */
int aq_oemrev; /* compared against the table OemRev */
int aq_cmpop; /* how to compare the oemrev number */
diff --git a/sys/dev/acpi/files.acpi b/sys/dev/acpi/files.acpi
index 28ddbee53bf..2f0badc306a 100644
--- a/sys/dev/acpi/files.acpi
+++ b/sys/dev/acpi/files.acpi
@@ -1,4 +1,4 @@
-# $NetBSD: files.acpi,v 1.46 2007/08/23 10:04:07 tnn Exp $
+# $NetBSD: files.acpi,v 1.47 2007/12/09 20:27:53 jmcneill Exp $
include "dev/acpi/acpica/files.acpica"
@@ -8,8 +8,9 @@ defparam opt_acpi.h ACPI_DSDT_FILE := "\"/dev/null\""
define acpiapmbus { }
define acpinodebus { }
+define acpiecdtbus { }
-device acpi: acpiapmbus, acpinodebus, sysmon_power, sysmon_taskq
+device acpi: acpiapmbus, acpinodebus, acpiecdtbus, sysmon_power, sysmon_taskq
attach acpi at acpibus
file dev/acpi/acpi.c acpi needs-flag
file dev/acpi/acpi_resource.c acpi
@@ -26,7 +27,9 @@ file dev/acpi/acpi_apm.c acpiapm
# ACPI Embedded Controller
device acpiec
attach acpiec at acpinodebus
-file dev/acpi/acpi_ec.c acpiec needs-flag
+device acpiecdt
+attach acpiecdt at acpiecdtbus
+file dev/acpi/acpi_ec.c acpiec|acpiecdt
# ACPI Lid Switch
device acpilid: sysmon_power
diff --git a/sys/dev/acpi/pckbc_acpi.c b/sys/dev/acpi/pckbc_acpi.c
index 063db3f85cd..e39b6d692ea 100644
--- a/sys/dev/acpi/pckbc_acpi.c
+++ b/sys/dev/acpi/pckbc_acpi.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pckbc_acpi.c,v 1.22 2007/10/19 11:59:35 ad Exp $ */
+/* $NetBSD: pckbc_acpi.c,v 1.23 2007/12/09 20:27:53 jmcneill Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -49,7 +49,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pckbc_acpi.c,v 1.22 2007/10/19 11:59:35 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pckbc_acpi.c,v 1.23 2007/12/09 20:27:53 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -232,10 +232,14 @@ pckbc_acpi_attach(struct device *parent, struct device *self,
t->t_sc = &first->sc_pckbc;
first->sc_pckbc.id = t;
+ if (!pmf_device_register(self, NULL, pckbc_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
first->sc_pckbc.intr_establish = pckbc_acpi_intr_establish;
config_defer(&first->sc_pckbc.sc_dv,
(void(*)(struct device *))pckbc_attach);
- }
+ } else if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
out:
acpi_resource_cleanup(&res);
}
diff --git a/sys/dev/acpi/pcppi_acpi.c b/sys/dev/acpi/pcppi_acpi.c
index 5a60dc74ade..7e516caae4c 100644
--- a/sys/dev/acpi/pcppi_acpi.c
+++ b/sys/dev/acpi/pcppi_acpi.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pcppi_acpi.c,v 1.7 2007/10/19 11:59:35 ad Exp $ */
+/* $NetBSD: pcppi_acpi.c,v 1.8 2007/12/09 20:27:53 jmcneill Exp $ */
/*
* Copyright (c) 2002 Jared D. McNeill <jmcneill@invisible.ca>
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pcppi_acpi.c,v 1.7 2007/10/19 11:59:35 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pcppi_acpi.c,v 1.8 2007/12/09 20:27:53 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -121,6 +121,9 @@ pcppi_acpi_attach(struct device *parent, struct device *self,
pcppi_attach(sc);
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
out:
acpi_resource_cleanup(&res);
}
diff --git a/sys/dev/apm/apm.c b/sys/dev/apm/apm.c
index 8b4a8f9ce9f..a0dd710e288 100644
--- a/sys/dev/apm/apm.c
+++ b/sys/dev/apm/apm.c
@@ -1,4 +1,4 @@
-/* $NetBSD: apm.c,v 1.15 2007/12/05 17:19:48 pooka Exp $ */
+/* $NetBSD: apm.c,v 1.16 2007/12/09 20:27:54 jmcneill Exp $ */
/*-
* Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: apm.c,v 1.15 2007/12/05 17:19:48 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: apm.c,v 1.16 2007/12/09 20:27:54 jmcneill Exp $");
#include "opt_apm.h"
@@ -316,11 +316,8 @@ apm_suspend(struct apm_softc *sc)
sc->sc_power_state = PWR_SUSPEND;
if (!(sc->sc_hwflags & APM_F_DONT_RUN_HOOKS)) {
- dopowerhooks(PWR_SOFTSUSPEND);
-
+ pmf_system_suspend();
apm_spl = splhigh();
-
- dopowerhooks(PWR_SUSPEND);
}
error = (*sc->sc_ops->aa_set_powstate)(sc->sc_cookie, APM_DEV_ALLDEVS,
@@ -345,11 +342,8 @@ apm_standby(struct apm_softc *sc)
sc->sc_power_state = PWR_STANDBY;
if (!(sc->sc_hwflags & APM_F_DONT_RUN_HOOKS)) {
- dopowerhooks(PWR_SOFTSTANDBY);
-
+ pmf_system_suspend();
apm_spl = splhigh();
-
- dopowerhooks(PWR_STANDBY);
}
error = (*sc->sc_ops->aa_set_powstate)(sc->sc_cookie, APM_DEV_ALLDEVS,
APM_SYS_STANDBY);
@@ -379,11 +373,8 @@ apm_resume(struct apm_softc *sc, u_int event_type, u_int event_info)
inittodr(time_second);
if (!(sc->sc_hwflags & APM_F_DONT_RUN_HOOKS)) {
- dopowerhooks(PWR_RESUME);
-
splx(apm_spl);
-
- dopowerhooks(PWR_SOFTRESUME);
+ pmf_system_resume();
}
apm_record_event(sc, event_type);
@@ -694,6 +685,9 @@ apm_attach(struct apm_softc *sc)
"kernel APM support disabled\n",
sc->sc_dev.dv_xname);
}
+
+ if (!pmf_device_register(&sc->sc_dev, NULL, NULL))
+ aprint_error_dev(&sc->sc_dev, "couldn't establish power handler\n");
}
void
diff --git a/sys/dev/ata/ata.c b/sys/dev/ata/ata.c
index bd1f556f060..fa55e3929d8 100644
--- a/sys/dev/ata/ata.c
+++ b/sys/dev/ata/ata.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ata.c,v 1.91 2007/10/19 11:59:36 ad Exp $ */
+/* $NetBSD: ata.c,v 1.92 2007/12/09 20:27:54 jmcneill Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.91 2007/10/19 11:59:36 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.92 2007/12/09 20:27:54 jmcneill Exp $");
#include "opt_ata.h"
@@ -106,7 +106,8 @@ const struct cdevsw atabus_cdevsw = {
extern struct cfdriver atabus_cd;
-static void atabus_powerhook(int, void *);
+static bool atabus_resume(device_t);
+static bool atabus_suspend(device_t);
/*
* atabusprint:
@@ -416,11 +417,8 @@ atabus_attach(struct device *parent, struct device *self, void *aux)
aprint_error("%s: unable to create kernel thread: error %d\n",
sc->sc_dev.dv_xname, error);
- sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- atabus_powerhook, sc);
- if (sc->sc_powerhook == NULL)
- printf("%s: WARNING: unable to establish power hook\n",
- sc->sc_dev.dv_xname);
+ if (!pmf_device_register(self, atabus_suspend, atabus_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
/*
@@ -502,10 +500,6 @@ atabus_detach(struct device *self, int flags)
while (chp->ch_thread != NULL)
(void) tsleep(&chp->ch_flags, PRIBIO, "atadown", 0);
- /* power hook */
- if (sc->sc_powerhook)
- powerhook_disestablish(sc->sc_powerhook);
-
/*
* Detach atapibus and its children.
*/
@@ -1475,33 +1469,38 @@ atabusioctl(dev_t dev, u_long cmd, void *addr, int flag,
return (error);
};
-static void
-atabus_powerhook(int why, void *hdl)
+static bool
+atabus_suspend(device_t dv)
{
- struct atabus_softc *sc = (struct atabus_softc *)hdl;
+ struct atabus_softc *sc = device_private(dv);
+ struct ata_channel *chp = sc->sc_chan;
+
+ ata_queue_idle(chp->ch_queue);
+
+ return true;
+}
+
+static bool
+atabus_resume(device_t dv)
+{
+ struct atabus_softc *sc = device_private(dv);
struct ata_channel *chp = sc->sc_chan;
int s;
- switch (why) {
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- /* freeze the queue and wait for the controller to be idle */
- ata_queue_idle(chp->ch_queue);
- break;
- case PWR_RESUME:
- printf("%s: resuming...\n", sc->sc_dev.dv_xname);
- s = splbio();
- KASSERT(chp->ch_queue->queue_freeze > 0);
- /* unfreeze the queue and reset drives (to wake them up) */
- chp->ch_queue->queue_freeze--;
- ata_reset_channel(chp, AT_WAIT);
+ /*
+ * XXX joerg: with wdc, the first channel unfreezes the controler.
+ * Move this the reset and queue idling into wdc.
+ */
+ s = splbio();
+ if (chp->ch_queue->queue_freeze == 0) {
splx(s);
- break;
- case PWR_SUSPEND:
- case PWR_STANDBY:
- case PWR_SOFTRESUME:
- break;
+ return true;
}
+ KASSERT(chp->ch_queue->queue_freeze > 0);
+ /* unfreeze the queue and reset drives */
+ chp->ch_queue->queue_freeze--;
+ ata_reset_channel(chp, AT_WAIT);
+ splx(s);
- return;
+ return true;
}
diff --git a/sys/dev/ata/atavar.h b/sys/dev/ata/atavar.h
index 3460505104a..b5e5bd0688b 100644
--- a/sys/dev/ata/atavar.h
+++ b/sys/dev/ata/atavar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: atavar.h,v 1.74 2007/07/09 21:00:31 ad Exp $ */
+/* $NetBSD: atavar.h,v 1.75 2007/12/09 20:27:54 jmcneill Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -102,7 +102,6 @@ struct atabus_softc {
struct ata_channel *sc_chan;
int sc_flags;
#define ATABUSCF_OPEN 0x01
- void *sc_powerhook;
};
/*
diff --git a/sys/dev/ata/wd.c b/sys/dev/ata/wd.c
index 94358fb8622..8c87abc7b27 100644
--- a/sys/dev/ata/wd.c
+++ b/sys/dev/ata/wd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: wd.c,v 1.350 2007/11/07 08:59:03 itohy Exp $ */
+/* $NetBSD: wd.c,v 1.351 2007/12/09 20:27:54 jmcneill Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
@@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.350 2007/11/07 08:59:03 itohy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.351 2007/12/09 20:27:54 jmcneill Exp $");
#include "opt_ata.h"
@@ -139,6 +139,8 @@ int wdactivate(struct device *, enum devact);
int wdprint(void *, char *);
void wdperror(const struct wd_softc *);
+static bool wd_suspend(device_t);
+
CFATTACH_DECL(wd, sizeof(struct wd_softc),
wdprobe, wdattach, wddetach, wdactivate);
@@ -189,9 +191,8 @@ void __wdstart(struct wd_softc*, struct buf *);
void wdrestart(void *);
void wddone(void *);
int wd_get_params(struct wd_softc *, u_int8_t, struct ataparams *);
-int wd_standby(struct wd_softc *, int);
+static int wd_standby(struct wd_softc *, int);
int wd_flushcache(struct wd_softc *, int);
-void wd_shutdown(void *);
int wd_getcache(struct wd_softc *, int *);
int wd_setcache(struct wd_softc *, int);
@@ -414,10 +415,6 @@ wdattach(struct device *parent, struct device *self, void *aux)
disk_init(&wd->sc_dk, wd->sc_dev.dv_xname, &wddkdriver);
disk_attach(&wd->sc_dk);
wd->sc_wdc_bio.lp = wd->sc_dk.dk_label;
- wd->sc_sdhook = shutdownhook_establish(wd_shutdown, wd);
- if (wd->sc_sdhook == NULL)
- aprint_error("%s: WARNING: unable to establish shutdown hook\n",
- wd->sc_dev.dv_xname);
#if NRND > 0
rnd_attach_source(&wd->rnd_source, wd->sc_dev.dv_xname,
RND_TYPE_DISK, 0);
@@ -425,6 +422,20 @@ wdattach(struct device *parent, struct device *self, void *aux)
/* Discover wedges on this disk. */
dkwedge_discover(&wd->sc_dk);
+
+ if (!pmf_device_register(self, wd_suspend, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+}
+
+static bool
+wd_suspend(device_t dv)
+{
+ struct wd_softc *sc = device_private(dv);
+
+ wd_flushcache(sc, AT_WAIT | AT_POLL);
+ wd_standby(sc, AT_WAIT | AT_POLL);
+
+ return true;
}
int
@@ -489,9 +500,7 @@ wddetach(struct device *self, int flags)
sc->sc_bscount = 0;
#endif
- /* Get rid of the shutdown hook. */
- if (sc->sc_sdhook != NULL)
- shutdownhook_disestablish(sc->sc_sdhook);
+ pmf_device_deregister(self);
#if NRND > 0
/* Unhook the entropy source. */
@@ -1857,7 +1866,7 @@ wd_setcache(struct wd_softc *wd, int bits)
return 0;
}
-int
+static int
wd_standby(struct wd_softc *wd, int flags)
{
struct ata_command ata_c;
@@ -1869,8 +1878,8 @@ wd_standby(struct wd_softc *wd, int flags)
ata_c.flags = flags;
ata_c.timeout = 30000; /* 30s timeout */
if (wd->atabus->ata_exec_command(wd->drvp, &ata_c) != ATACMD_COMPLETE) {
- printf("%s: standby immediate command didn't complete\n",
- wd->sc_dev.dv_xname);
+ aprint_error_dev(&wd->sc_dev,
+ "standby immediate command didn't complete\n");
return EIO;
}
if (ata_c.flags & AT_ERROR) {
@@ -1880,8 +1889,7 @@ wd_standby(struct wd_softc *wd, int flags)
if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
char sbuf[sizeof(at_errbits) + 64];
bitmask_snprintf(ata_c.flags, at_errbits, sbuf, sizeof(sbuf));
- printf("%s: wd_standby: status=%s\n", wd->sc_dev.dv_xname,
- sbuf);
+ aprint_error_dev(&wd->sc_dev, "wd_standby: status=%s\n", sbuf);
return EIO;
}
return 0;
@@ -1929,14 +1937,6 @@ wd_flushcache(struct wd_softc *wd, int flags)
return 0;
}
-void
-wd_shutdown(void *arg)
-{
-
- struct wd_softc *wd = arg;
- wd_flushcache(wd, AT_POLL);
-}
-
/*
* Allocate space for a ioctl queue structure. Mostly taken from
* scsipi_ioctl.c
diff --git a/sys/dev/ata/wdvar.h b/sys/dev/ata/wdvar.h
index 5bd337fda8b..f909abab5c0 100644
--- a/sys/dev/ata/wdvar.h
+++ b/sys/dev/ata/wdvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: wdvar.h,v 1.32 2005/12/11 12:21:14 christos Exp $ */
+/* $NetBSD: wdvar.h,v 1.33 2007/12/09 20:27:55 jmcneill Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -66,8 +66,6 @@ struct wd_softc {
int retries; /* number of xfer retry */
- void *sc_sdhook; /* our shutdown hook */
-
#ifdef WD_SOFTBADSECT
SLIST_HEAD(, disk_badsectors) sc_bslist;
u_int sc_bscount;
diff --git a/sys/dev/audio.c b/sys/dev/audio.c
index f086955e929..dee292c5ab2 100644
--- a/sys/dev/audio.c
+++ b/sys/dev/audio.c
@@ -1,4 +1,4 @@
-/* $NetBSD: audio.c,v 1.226 2007/12/05 17:19:47 pooka Exp $ */
+/* $NetBSD: audio.c,v 1.227 2007/12/09 20:27:51 jmcneill Exp $ */
/*
* Copyright (c) 1991-1993 Regents of the University of California.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.226 2007/12/05 17:19:47 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.227 2007/12/09 20:27:51 jmcneill Exp $");
#include "audio.h"
#if NAUDIO > 0
@@ -102,6 +102,7 @@ int audiodebug = AUDIO_DEBUG;
#define SPECIFIED(x) (x != ~0)
#define SPECIFIED_CH(x) (x != (u_char)~0)
+int audio_idle_timeout = 30;
int audio_blk_ms = AUDIO_BLK_MS;
int audiosetinfo(struct audio_softc *, struct audio_info *);
@@ -173,7 +174,17 @@ void audioattach(struct device *, struct device *, void *);
int audiodetach(struct device *, int);
int audioactivate(struct device *, enum devact);
-void audio_powerhook(int, void *);
+static void audio_idle(void *);
+static void audio_activity(device_t, devactive_t);
+
+static bool audio_suspend(device_t dv);
+static bool audio_resume(device_t dv);
+static void audio_volume_down(device_t);
+static void audio_volume_up(device_t);
+static void audio_volume_toggle(device_t);
+
+static void audio_mixer_capture(struct audio_softc *);
+static void audio_mixer_restore(struct audio_softc *);
static void audio_softintr_rd(void *);
static void audio_softintr_wr(void *);
@@ -333,6 +344,8 @@ audioattach(struct device *parent, struct device *self, void *aux)
return;
}
+ sc->sc_lastgain = 128;
+
if ((error = audio_set_defaults(sc, 0))) {
aprint_error("audioattach: audio_set_defaults() failed\n");
sc->hw_if = NULL;
@@ -419,6 +432,9 @@ audioattach(struct device *parent, struct device *self, void *aux)
au_setup_ports(sc, &sc->sc_inports, &mi,
itable);
}
+ if (strcmp(mi.label.name, AudioNdac) == 0 &&
+ sc->sc_outports.master == -1)
+ sc->sc_outports.master = mi.index;
} else if (mi.mixer_class == mclass) {
if (strcmp(mi.label.name, AudioNmonitor) == 0)
sc->sc_monitor_port = mi.index;
@@ -467,11 +483,25 @@ audioattach(struct device *parent, struct device *self, void *aux)
sc->sc_inports.allports, sc->sc_inports.master,
sc->sc_outports.allports, sc->sc_outports.master));
- sc->sc_powerhook = powerhook_establish(sc->dev.dv_xname,
- audio_powerhook, sc);
- if (sc->sc_powerhook == NULL)
- aprint_error("%s: can't establish powerhook\n",
- sc->dev.dv_xname);
+ callout_init(&sc->sc_idle_counter, 0);
+ callout_setfunc(&sc->sc_idle_counter, audio_idle, self);
+
+ if (!pmf_device_register(self, audio_suspend, audio_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ if (!device_active_register(self, audio_activity))
+ aprint_error_dev(self, "couldn't register activity handler\n");
+
+ if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_DOWN,
+ audio_volume_down, true))
+ aprint_error_dev(self, "couldn't add volume down handler\n");
+ if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_UP,
+ audio_volume_up, true))
+ aprint_error_dev(self, "couldn't add volume up handler\n");
+ if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_TOGGLE,
+ audio_volume_toggle, true))
+ aprint_error_dev(self, "couldn't add volume toggle handler\n");
+
+ callout_schedule(&sc->sc_idle_counter, audio_idle_timeout * hz);
}
int
@@ -503,6 +533,17 @@ audiodetach(struct device *self, int flags)
sc->sc_dying = true;
+ pmf_event_deregister(self, PMFE_AUDIO_VOLUME_DOWN,
+ audio_volume_down, true);
+ pmf_event_deregister(self, PMFE_AUDIO_VOLUME_UP,
+ audio_volume_up, true);
+ pmf_event_deregister(self, PMFE_AUDIO_VOLUME_TOGGLE,
+ audio_volume_toggle, true);
+
+ callout_stop(&sc->sc_idle_counter);
+
+ pmf_device_deregister(self);
+
wakeup(&sc->sc_wchan);
wakeup(&sc->sc_rchan);
s = splaudio();
@@ -529,10 +570,6 @@ audiodetach(struct device *self, int flags)
vdevgone(maj, mn | AUDIOCTL_DEVICE, mn | AUDIOCTL_DEVICE, VCHR);
vdevgone(maj, mn | MIXER_DEVICE, mn | MIXER_DEVICE, VCHR);
- if (sc->sc_powerhook != NULL) {
- powerhook_disestablish(sc->sc_powerhook);
- sc->sc_powerhook = NULL;
- }
if (sc->sc_sih_rd) {
softint_disestablish(sc->sc_sih_rd);
sc->sc_sih_rd = NULL;
@@ -542,6 +579,8 @@ audiodetach(struct device *self, int flags)
sc->sc_sih_wr = NULL;
}
+ callout_destroy(&sc->sc_idle_counter);
+
return 0;
}
@@ -949,8 +988,8 @@ audioopen(dev_t dev, int flags, int ifmt, struct lwp *l)
if (sc->sc_dying)
return EIO;
- if (sc->hw_if->powerstate && sc->sc_opencnt <= 0)
- sc->hw_if->powerstate(sc->hw_hdl, AUDIOPOWER_ON);
+ device_active(&sc->dev, DVA_SYSTEM);
+
sc->sc_opencnt++;
sc->sc_refcnt++;
@@ -983,6 +1022,9 @@ audioclose(dev_t dev, int flags, int ifmt, struct lwp *l)
unit = AUDIOUNIT(dev);
sc = audio_cd.cd_devs[unit];
+
+ device_active(&sc->dev, DVA_SYSTEM);
+
switch (AUDIODEV(dev)) {
case SOUND_DEVICE:
case AUDIO_DEVICE:
@@ -1000,8 +1042,6 @@ audioclose(dev_t dev, int flags, int ifmt, struct lwp *l)
}
sc->sc_opencnt--;
- if (sc->hw_if->powerstate && sc->sc_opencnt <= 0)
- sc->hw_if->powerstate(sc->hw_hdl, AUDIOPOWER_OFF);
return error;
}
@@ -1019,6 +1059,8 @@ audioread(dev_t dev, struct uio *uio, int ioflag)
if (sc->sc_dying)
return EIO;
+ device_active(&sc->dev, DVA_SYSTEM);
+
sc->sc_refcnt++;
switch (AUDIODEV(dev)) {
case SOUND_DEVICE:
@@ -1051,6 +1093,8 @@ audiowrite(dev_t dev, struct uio *uio, int ioflag)
if (sc->sc_dying)
return EIO;
+ device_active(&sc->dev, DVA_SYSTEM);
+
sc->sc_refcnt++;
switch (AUDIODEV(dev)) {
case SOUND_DEVICE:
@@ -1085,6 +1129,7 @@ audioioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
case SOUND_DEVICE:
case AUDIO_DEVICE:
case AUDIOCTL_DEVICE:
+ device_active(&sc->dev, DVA_SYSTEM);
error = audio_ioctl(sc, cmd, addr, flag, l);
break;
case MIXER_DEVICE:
@@ -1109,6 +1154,8 @@ audiopoll(dev_t dev, int events, struct lwp *l)
if (sc->sc_dying)
return POLLHUP;
+ device_active(&sc->dev, DVA_SYSTEM);
+
sc->sc_refcnt++;
switch (AUDIODEV(dev)) {
case SOUND_DEVICE:
@@ -1138,6 +1185,8 @@ audiokqfilter(dev_t dev, struct knote *kn)
if (sc->sc_dying)
return 1;
+ device_active(&sc->dev, DVA_SYSTEM);
+
sc->sc_refcnt++;
switch (AUDIODEV(dev)) {
case SOUND_DEVICE:
@@ -1166,6 +1215,8 @@ audiommap(dev_t dev, off_t off, int prot)
if (sc->sc_dying)
return -1;
+ device_active(&sc->dev, DVA_SYSTEM); /* XXXJDM */
+
sc->sc_refcnt++;
switch (AUDIODEV(dev)) {
case SOUND_DEVICE:
@@ -3713,12 +3764,18 @@ mixer_ioctl(struct audio_softc *sc, u_long cmd, void *addr, int flag,
struct lwp *l)
{
const struct audio_hw_if *hw;
+ mixer_ctrl_t *mc;
int error;
DPRINTF(("mixer_ioctl(%lu,'%c',%lu)\n",
IOCPARM_LEN(cmd), (char)IOCGROUP(cmd), cmd&0xff));
hw = sc->hw_if;
error = EINVAL;
+
+ /* we can return cached values if we are sleeping */
+ if (cmd != AUDIO_MIXER_READ)
+ device_active(&sc->dev, DVA_SYSTEM);
+
switch (cmd) {
case FIOASYNC:
mixer_remove(sc, l); /* remove old entry */
@@ -3746,7 +3803,19 @@ mixer_ioctl(struct audio_softc *sc, u_long cmd, void *addr, int flag,
case AUDIO_MIXER_READ:
DPRINTF(("AUDIO_MIXER_READ\n"));
- error = hw->get_port(sc->hw_hdl, (mixer_ctrl_t *)addr);
+ mc = (mixer_ctrl_t *)addr;
+
+ if (device_is_active(sc->sc_dev) ||
+ sc->sc_mixer_state == NULL)
+ error = hw->get_port(sc->hw_hdl, mc);
+ else if (mc->dev >= sc->sc_nmixer_states)
+ error = ENXIO;
+ else {
+ int dev = mc->dev;
+ memcpy(mc, &sc->sc_mixer_state[dev],
+ sizeof(mixer_ctrl_t));
+ error = 0;
+ }
break;
case AUDIO_MIXER_WRITE:
@@ -3814,30 +3883,195 @@ audioprint(void *aux, const char *pnp)
#endif /* NAUDIO > 0 || (NMIDI > 0 || NMIDIBUS > 0) */
#if NAUDIO > 0
-void
-audio_powerhook(int why, void *aux)
+static void
+audio_mixer_capture(struct audio_softc *sc)
{
- struct audio_softc *sc;
- const struct audio_hw_if *hwp;
+ mixer_devinfo_t mi;
+ mixer_ctrl_t *mc;
- sc = (struct audio_softc *)aux;
- hwp = sc->hw_if;
+ for (mi.index = 0; ; mi.index++)
+ if (sc->hw_if->query_devinfo(sc->hw_hdl, &mi) != 0)
+ break;
- switch (why) {
- case PWR_SOFTSUSPEND:
- if (sc->sc_pbus == true)
- hwp->halt_output(sc->hw_hdl);
- if (sc->sc_rbus == true)
- hwp->halt_input(sc->hw_hdl);
- break;
- case PWR_SOFTRESUME:
- if (sc->sc_pbus == true)
- audiostartp(sc);
- if (sc->sc_rbus == true)
- audiostartr(sc);
- break;
+#ifdef DIAGNOSTIC
+ if (sc->sc_mixer_state != NULL && sc->sc_nmixer_states != mi.index) {
+ free(sc->sc_mixer_state, M_DEVBUF);
+ sc->sc_mixer_state = NULL;
+ }
+#endif
+
+ sc->sc_nmixer_states = mi.index;
+ if (sc->sc_mixer_state == NULL)
+ sc->sc_mixer_state = malloc(
+ sizeof(mixer_ctrl_t) * sc->sc_nmixer_states,
+ M_DEVBUF, M_NOWAIT);
+ if (sc->sc_mixer_state == NULL) {
+ aprint_error("%s: couldn't allocate memory for mixer state\n",
+ device_xname(&sc->dev));
+ return;
+ }
+
+ for (mi.index = 0; ; mi.index++) {
+ if (sc->hw_if->query_devinfo(sc->hw_hdl, &mi) != 0)
+ break;
+ if (mi.type == AUDIO_MIXER_CLASS)
+ continue;
+ mc = &sc->sc_mixer_state[mi.index];
+ mc->dev = mi.index;
+ mc->type = mi.type;
+ (void)sc->hw_if->get_port(sc->hw_hdl, mc);
}
return;
}
+
+static void
+audio_mixer_restore(struct audio_softc *sc)
+{
+ mixer_devinfo_t mi;
+ mixer_ctrl_t *mc;
+
+ if (sc->sc_mixer_state == NULL)
+ return;
+
+ for (mi.index = 0; ; mi.index++) {
+ if (sc->hw_if->query_devinfo(sc->hw_hdl, &mi) != 0)
+ break;
+ if (mi.type == AUDIO_MIXER_CLASS)
+ continue;
+ mc = &sc->sc_mixer_state[mi.index];
+ (void)sc->hw_if->set_port(sc->hw_hdl, mc);
+ }
+ if (sc->hw_if->commit_settings)
+ sc->hw_if->commit_settings(sc->hw_hdl);
+
+ return;
+}
+
+static void
+audio_idle(void *arg)
+{
+ device_t dv = arg;
+ struct audio_softc *sc = device_private(dv);
+
+#ifdef PNP_DEBUG
+ extern int pnp_debug_idle;
+ if (pnp_debug_idle)
+ printf("%s: idle handler called\n", device_xname(dv));
+#endif
+
+ /* XXX joerg Make pmf_device_suspend handle children? */
+ if (!pmf_device_suspend(dv))
+ return;
+
+ if (!pmf_device_suspend(sc->sc_dev))
+ pmf_device_resume(dv);
+}
+
+static void
+audio_activity(device_t dv, devactive_t type)
+{
+ struct audio_softc *sc = device_private(dv);
+
+ if (type != DVA_SYSTEM)
+ return;
+
+ callout_schedule(&sc->sc_idle_counter, audio_idle_timeout * hz);
+
+ if (!device_is_active(dv)) {
+ /* XXX joerg How to deal with a failing resume... */
+ pmf_device_resume(sc->sc_dev);
+ pmf_device_resume(dv);
+ }
+}
+
+static bool
+audio_suspend(device_t dv)
+{
+ struct audio_softc *sc = device_private(dv);
+ const struct audio_hw_if *hwp = sc->hw_if;
+ int (s);
+
+ s = splaudio();
+ audio_mixer_capture(sc);
+ if (sc->sc_pbus == true)
+ hwp->halt_output(sc->hw_hdl);
+ if (sc->sc_rbus == true)
+ hwp->halt_input(sc->hw_hdl);
+ callout_stop(&sc->sc_idle_counter);
+ splx(s);
+
+ return true;
+}
+
+static bool
+audio_resume(device_t dv)
+{
+ struct audio_softc *sc = device_private(dv);
+ int s;
+
+ s = splaudio();
+ audio_mixer_restore(sc);
+ if (sc->sc_pbus == true)
+ audiostartp(sc);
+ if (sc->sc_rbus == true)
+ audiostartr(sc);
+ splx(s);
+
+ return true;
+}
+
+static void
+audio_volume_down(device_t dv)
+{
+ struct audio_softc *sc = device_private(dv);
+ u_int gain, newgain;
+ u_char balance;
+ int s;
+
+ s = splaudio();
+ au_get_gain(sc, &sc->sc_outports, &gain, &balance);
+ newgain = gain - 32;
+ if (newgain > 255)
+ newgain = 0;
+ au_set_gain(sc, &sc->sc_outports, newgain, balance);
+ splx(s);
+}
+
+static void
+audio_volume_up(device_t dv)
+{
+ struct audio_softc *sc = device_private(dv);
+ u_int gain, newgain;
+ u_char balance;
+ int s;
+
+ s = splaudio();
+ au_get_gain(sc, &sc->sc_outports, &gain, &balance);
+ newgain = gain + 32;
+ if (newgain > 255)
+ newgain = 255;
+ au_set_gain(sc, &sc->sc_outports, newgain, balance);
+ splx(s);
+}
+
+static void
+audio_volume_toggle(device_t dv)
+{
+ struct audio_softc *sc = device_private(dv);
+ u_int gain, newgain;
+ u_char balance;
+ int s;
+
+ s = splaudio();
+ au_get_gain(sc, &sc->sc_outports, &gain, &balance);
+ if (gain != 0) {
+ sc->sc_lastgain = gain;
+ newgain = sc->sc_lastgain;
+ } else
+ newgain = 0;
+ au_set_gain(sc, &sc->sc_outports, newgain, balance);
+ splx(s);
+}
+
#endif /* NAUDIO > 0 */
diff --git a/sys/dev/audiovar.h b/sys/dev/audiovar.h
index 40026d79e35..75fc2193d41 100644
--- a/sys/dev/audiovar.h
+++ b/sys/dev/audiovar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: audiovar.h,v 1.39 2007/02/21 22:59:58 thorpej Exp $ */
+/* $NetBSD: audiovar.h,v 1.40 2007/12/09 20:27:52 jmcneill Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -225,7 +225,12 @@ struct audio_softc {
long sc_rblktime; /* nominal time between interrupts */
#endif
- void *sc_powerhook;
+ u_int sc_lastgain;
+
+ mixer_ctrl_t *sc_mixer_state;
+ int sc_nmixer_states;
+
+ callout_t sc_idle_counter;
};
#endif /* _SYS_DEV_AUDIOVAR_H_ */
diff --git a/sys/dev/cardbus/cardbus.c b/sys/dev/cardbus/cardbus.c
index f960ca48875..d52caf5f88a 100644
--- a/sys/dev/cardbus/cardbus.c
+++ b/sys/dev/cardbus/cardbus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cardbus.c,v 1.80 2007/12/01 17:56:59 jmcneill Exp $ */
+/* $NetBSD: cardbus.c,v 1.81 2007/12/09 20:27:55 jmcneill Exp $ */
/*
* Copyright (c) 1997, 1998, 1999 and 2000
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cardbus.c,v 1.80 2007/12/01 17:56:59 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cardbus.c,v 1.81 2007/12/09 20:27:55 jmcneill Exp $");
#include "opt_cardbus.h"
@@ -88,6 +88,8 @@ static int cardbus_read_tuples(struct cardbus_attach_args *,
static void enable_function(struct cardbus_softc *, int, int);
static void disable_function(struct cardbus_softc *, int);
+static bool cardbus_child_register(device_t);
+
CFATTACH_DECL2(cardbus, sizeof(struct cardbus_softc),
cardbusmatch, cardbusattach, NULL, NULL,
cardbus_rescan, cardbus_childdetached);
@@ -141,6 +143,9 @@ cardbusattach(struct device *parent, struct device *self, void *aux)
sc->sc_rbus_iot = cba->cba_rbus_iot;
sc->sc_rbus_memt = cba->cba_rbus_memt;
#endif
+
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
@@ -403,6 +408,7 @@ cardbus_attach_card(struct cardbus_softc *sc)
return (0);
}
+ device_pmf_driver_set_child_register(&sc->sc_dev, cardbus_child_register);
cardbus_rescan(&sc->sc_dev, "cardbus", wildcard);
return (1); /* XXX */
}
@@ -925,76 +931,92 @@ decode_tuple(u_int8_t *tuple, u_int8_t *end,
/*
* XXX: this is another reason why this code should be shared with PCI.
*/
-int
-cardbus_powerstate(cardbus_devfunc_t ct, pcitag_t tag, const int *newstate,
- int *oldstate)
+static int
+cardbus_get_powerstate_int(cardbus_devfunc_t ct, cardbustag_t tag,
+ cardbusreg_t *state, int offset)
{
+ cardbusreg_t value, now;
cardbus_chipset_tag_t cc = ct->ct_cc;
cardbus_function_tag_t cf = ct->ct_cf;
+ value = cardbus_conf_read(cc, cf, 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
+cardbus_get_powerstate(cardbus_devfunc_t ct, cardbustag_t tag,
+ cardbusreg_t *state)
+{
+ cardbus_chipset_tag_t cc = ct->ct_cc;
+ cardbus_function_tag_t cf = ct->ct_cf;
int offset;
- pcireg_t value, cap, now;
+ cardbusreg_t value;
- if (!cardbus_get_capability(cc, cf, tag, PCI_CAP_PWRMGMT, &offset,
- &value))
+ if (!cardbus_get_capability(cc, cf, tag, PCI_CAP_PWRMGMT, &offset, &value))
return EOPNOTSUPP;
- cap = value >> 16;
+ return cardbus_get_powerstate_int(ct, tag, state, offset);
+}
+
+static int
+cardbus_set_powerstate_int(cardbus_devfunc_t ct, cardbustag_t tag,
+ cardbusreg_t state, int offset, cardbusreg_t cap_reg)
+{
+ cardbus_chipset_tag_t cc = ct->ct_cc;
+ cardbus_function_tag_t cf = ct->ct_cf;
+
+ cardbusreg_t value, cap, now;
+
+ cap = cap_reg >> PCI_PMCR_SHIFT;
value = cardbus_conf_read(cc, cf, 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)
+ value &= ~PCI_PMCSR_STATE_MASK;
+
+ if (now == state)
return 0;
- switch (*newstate) {
- case PCI_PWR_D0:
- if (now == PCI_PMCSR_STATE_D0)
- return 0;
+ switch (state) {
+ case PCI_PMCSR_STATE_D0:
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)
+ case PCI_PMCSR_STATE_D1:
+ if (now == PCI_PMCSR_STATE_D2 || now == PCI_PMCSR_STATE_D3) {
+ printf("invalid transition from %d to D1\n", (int)now);
return EINVAL;
- if (!(cap & PCI_PMCR_D1SUPP))
+ }
+ if (!(cap & PCI_PMCR_D1SUPP)) {
+ printf("D1 not supported\n");
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)
+ case PCI_PMCSR_STATE_D2:
+ if (now == PCI_PMCSR_STATE_D3) {
+ printf("invalid transition from %d to D2\n", (int)now);
return EINVAL;
- if (!(cap & PCI_PMCR_D2SUPP))
+ }
+ if (!(cap & PCI_PMCR_D2SUPP)) {
+ printf("D2 not supported\n");
return EOPNOTSUPP;
+ }
value |= PCI_PMCSR_STATE_D2;
break;
- case PCI_PWR_D3:
- if (now == PCI_PMCSR_STATE_D3)
- return 0;
+ case PCI_PMCSR_STATE_D3:
value |= PCI_PMCSR_STATE_D3;
break;
default:
return EINVAL;
}
+
cardbus_conf_write(cc, cf, tag, offset + PCI_PMCSR, value);
DELAY(1000);
@@ -1002,41 +1024,20 @@ cardbus_powerstate(cardbus_devfunc_t ct, pcitag_t tag, const int *newstate,
}
int
-cardbus_setpowerstate(const char *dvname, cardbus_devfunc_t ct, pcitag_t tag,
- int newpwr)
+cardbus_set_powerstate(cardbus_devfunc_t ct, cardbustag_t tag, cardbusreg_t state)
{
- int oldpwr, error;
-
- if ((error = cardbus_powerstate(ct, tag, &newpwr, &oldpwr)) != 0)
- return error;
-
- if (oldpwr == newpwr)
- return 0;
+ cardbus_chipset_tag_t cc = ct->ct_cc;
+ cardbus_function_tag_t cf = ct->ct_cf;
+ int offset;
+ cardbusreg_t value;
- if (oldpwr > newpwr) {
- printf("%s: sleeping to power state D%d\n", dvname, oldpwr);
- return 0;
- }
+ if (!cardbus_get_capability(cc, cf, tag, PCI_CAP_PWRMGMT, &offset,
+ &value))
+ return EOPNOTSUPP;
- /* oldpwr < newpwr */
- switch (oldpwr) {
- case PCI_PWR_D3:
- /*
- * XXX: This is because none of the devices do
- * the necessary song and dance for now to wakeup
- * Once this
- */
- printf("%s: cannot wake up from power state D%d\n",
- dvname, oldpwr);
- return EINVAL;
- default:
- printf("%s: waking up from power state D%d\n",
- dvname, oldpwr);
- return 0;
- }
+ return cardbus_set_powerstate_int(ct, tag, state, offset, value);
}
-
#ifdef CARDBUS_DEBUG
static const char *tuple_name(int);
static const char *tuple_names[] = {
@@ -1095,3 +1096,137 @@ print_tuple(u_int8_t *tuple, int len, void *data)
}
}
#endif
+
+void
+cardbus_conf_capture(cardbus_chipset_tag_t cc, cardbus_function_tag_t cf,
+ cardbustag_t tag, struct cardbus_conf_state *pcs)
+{
+ int off;
+
+ for (off = 0; off < 16; off++)
+ pcs->reg[off] = cardbus_conf_read(cc, cf, tag, (off * 4));
+}
+
+void
+cardbus_conf_restore(cardbus_chipset_tag_t cc, cardbus_function_tag_t cf,
+ cardbustag_t tag, struct cardbus_conf_state *pcs)
+{
+ int off;
+ cardbusreg_t val;
+
+ for (off = 15; off >= 0; off--) {
+ val = cardbus_conf_read(cc, cf, tag, (off * 4));
+ if (val != pcs->reg[off])
+ cardbus_conf_write(cc, cf,tag, (off * 4), pcs->reg[off]);
+ }
+}
+
+void
+cardbus_disable_retry(cardbus_chipset_tag_t cc, cardbus_function_tag_t cf,
+ cardbustag_t tag)
+{
+ cardbusreg_t retry;
+
+ /*
+ * Disable retry timeout to keep PCI Tx retries from
+ * interfering with ACPI C3 CPU state.
+ */
+ retry = cardbus_conf_read(cc, cf, tag, PCI_RETRY_TIMEOUT_REG);
+ retry &= ~PCI_RETRY_TIMEOUT_REG_MASK;
+ cardbus_conf_write(cc, cf, tag, PCI_RETRY_TIMEOUT_REG, retry);
+}
+
+struct cardbus_child_power {
+ struct cardbus_conf_state p_cardbusconf;
+ cardbus_devfunc_t p_ct;
+ cardbustag_t p_tag;
+ cardbus_chipset_tag_t p_cc;
+ cardbus_function_tag_t p_cf;
+ cardbusreg_t p_pm_cap;
+ bool p_has_pm;
+ int p_pm_offset;
+};
+
+static bool
+cardbus_child_suspend(device_t dv)
+{
+ struct cardbus_child_power *priv = device_pmf_bus_private(dv);
+
+ cardbus_conf_capture(priv->p_cc, priv->p_cf, priv->p_tag,
+ &priv->p_cardbusconf);
+
+ if (priv->p_has_pm &&
+ cardbus_set_powerstate_int(priv->p_ct, priv->p_tag,
+ PCI_PMCSR_STATE_D3, priv->p_pm_offset, priv->p_pm_cap)) {
+ aprint_error_dev(dv, "unsupported state, continuing.\n");
+ return false;
+ }
+
+ Cardbus_function_disable(priv->p_ct);
+
+ return true;
+}
+
+static bool
+cardbus_child_resume(device_t dv)
+{
+ struct cardbus_child_power *priv = device_pmf_bus_private(dv);
+
+ Cardbus_function_enable(priv->p_ct);
+
+ if (priv->p_has_pm &&
+ cardbus_set_powerstate_int(priv->p_ct, priv->p_tag,
+ PCI_PMCSR_STATE_D0, priv->p_pm_offset, priv->p_pm_cap)) {
+ aprint_error_dev(dv, "unsupported state, continuing.\n");
+ return false;
+ }
+
+ cardbus_conf_restore(priv->p_cc, priv->p_cf, priv->p_tag,
+ &priv->p_cardbusconf);
+
+ return true;
+}
+
+static void
+cardbus_child_deregister(device_t dv)
+{
+ struct cardbus_child_power *priv = device_pmf_bus_private(dv);
+
+ free(priv, M_DEVBUF);
+}
+
+static bool
+cardbus_child_register(device_t child)
+{
+ device_t self = device_parent(child);
+ struct cardbus_softc *sc = device_private(self);
+ struct cardbus_devfunc *ct;
+ struct cardbus_child_power *priv;
+ int off;
+ cardbusreg_t reg;
+
+ ct = sc->sc_funcs[device_locator(child, CARDBUSCF_FUNCTION)];
+
+ priv = malloc(sizeof(*priv), M_DEVBUF, M_WAITOK);
+
+ priv->p_ct = ct;
+ priv->p_cc = ct->ct_cf;
+ priv->p_cf = ct->ct_cf;
+ priv->p_tag = cardbus_make_tag(priv->p_cc, priv->p_cf, ct->ct_bus,
+ ct->ct_func);
+
+ if (cardbus_get_capability(priv->p_cc, priv->p_cf, priv->p_tag,
+ PCI_CAP_PWRMGMT, &off, &reg)) {
+ priv->p_has_pm = true;
+ priv->p_pm_offset = off;
+ priv->p_pm_cap = reg;
+ } else {
+ priv->p_has_pm = false;
+ priv->p_pm_offset = -1;
+ }
+
+ device_pmf_bus_register(child, priv, cardbus_child_suspend,
+ cardbus_child_resume, cardbus_child_deregister);
+
+ return true;
+}
diff --git a/sys/dev/cardbus/cardbusvar.h b/sys/dev/cardbus/cardbusvar.h
index 00e6b0e4986..5472db2ee4f 100644
--- a/sys/dev/cardbus/cardbusvar.h
+++ b/sys/dev/cardbus/cardbusvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: cardbusvar.h,v 1.36 2007/11/16 18:36:53 dyoung Exp $ */
+/* $NetBSD: cardbusvar.h,v 1.37 2007/12/09 20:27:55 jmcneill Exp $ */
/*
* Copyright (c) 1998, 1999 and 2000
@@ -199,6 +199,9 @@ struct cardbus_softc {
struct cardbus_devfunc *sc_funcs[8]; /* list of cardbus device functions */
};
+struct cardbus_conf_state {
+ cardbusreg_t reg[16];
+};
/*
* struct cardbus_devfunc:
@@ -326,10 +329,18 @@ int cardbus_restore_bar(cardbus_devfunc_t);
int cardbus_function_enable(struct cardbus_softc *, int);
int cardbus_function_disable(struct cardbus_softc *, int);
+void cardbus_disable_retry(cardbus_chipset_tag_t, cardbus_function_tag_t,
+ cardbustag_t);
+
int cardbus_get_capability(cardbus_chipset_tag_t, cardbus_function_tag_t,
cardbustag_t, int, int *, cardbusreg_t *);
-int cardbus_powerstate(cardbus_devfunc_t, pcitag_t, const int *, int *);
-int cardbus_setpowerstate(const char *, cardbus_devfunc_t, pcitag_t, int);
+int cardbus_get_powerstate(cardbus_devfunc_t, cardbustag_t, cardbusreg_t *);
+int cardbus_set_powerstate(cardbus_devfunc_t, cardbustag_t, cardbusreg_t);
+
+void cardbus_conf_capture(cardbus_chipset_tag_t, cardbus_function_tag_t,
+ cardbustag_t, struct cardbus_conf_state *);
+void cardbus_conf_restore(cardbus_chipset_tag_t, cardbus_function_tag_t,
+ cardbustag_t, struct cardbus_conf_state *);
#define Cardbus_function_enable(ct) cardbus_function_enable((ct)->ct_sc, (ct)->ct_func)
#define Cardbus_function_disable(ct) cardbus_function_disable((ct)->ct_sc, (ct)->ct_func)
diff --git a/sys/dev/cardbus/cardslot.c b/sys/dev/cardbus/cardslot.c
index 85bb8ab12ab..053e0d19d8b 100644
--- a/sys/dev/cardbus/cardslot.c
+++ b/sys/dev/cardbus/cardslot.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cardslot.c,v 1.37 2007/12/01 05:51:16 jmcneill Exp $ */
+/* $NetBSD: cardslot.c,v 1.38 2007/12/09 20:27:55 jmcneill Exp $ */
/*
* Copyright (c) 1999 and 2000
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cardslot.c,v 1.37 2007/12/01 05:51:16 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cardslot.c,v 1.38 2007/12/09 20:27:55 jmcneill Exp $");
#include "opt_cardslot.h"
@@ -166,6 +166,9 @@ cardslotattach(struct device *parent, struct device *self,
/* attach deferred */
cardslot_event_throw(sc, CARDSLOT_EVENT_INSERTION_16);
}
+
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
diff --git a/sys/dev/cardbus/if_ath_cardbus.c b/sys/dev/cardbus/if_ath_cardbus.c
index 53def036ac3..7ac2f0b28a2 100644
--- a/sys/dev/cardbus/if_ath_cardbus.c
+++ b/sys/dev/cardbus/if_ath_cardbus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ath_cardbus.c,v 1.20 2007/11/21 02:10:45 dyoung Exp $ */
+/* $NetBSD: if_ath_cardbus.c,v 1.21 2007/12/09 20:27:55 jmcneill Exp $ */
/*
* Copyright (c) 2003
* Ichiro FUKUHARA <ichiro@ichiro.org>.
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ath_cardbus.c,v 1.20 2007/11/21 02:10:45 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ath_cardbus.c,v 1.21 2007/12/09 20:27:55 jmcneill Exp $");
#include "opt_inet.h"
#include "bpfilter.h"
@@ -107,13 +107,11 @@ struct ath_cardbus_softc {
int sc_intrline; /* interrupt line */
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
- void *sc_sdhook;
};
int ath_cardbus_match(struct device *, struct cfdata *, void *);
void ath_cardbus_attach(struct device *, struct device *, void *);
int ath_cardbus_detach(struct device *, int);
-void ath_cardbus_shutdown(void *arg);
CFATTACH_DECL(ath_cardbus, sizeof(struct ath_cardbus_softc),
ath_cardbus_match, ath_cardbus_attach, ath_cardbus_detach, ath_activate);
@@ -122,7 +120,20 @@ void ath_cardbus_setup(struct ath_cardbus_softc *);
int ath_cardbus_enable(struct ath_softc *);
void ath_cardbus_disable(struct ath_softc *);
-void ath_cardbus_power(struct ath_softc *, int);
+
+static bool
+ath_cardbus_resume(device_t dv)
+{
+ struct ath_cardbus_softc *csc = device_private(dv);
+ cardbus_devfunc_t ct = csc->sc_ct;
+ cardbus_chipset_tag_t cc = ct->ct_cc;
+ cardbus_function_tag_t cf = ct->ct_cf;
+
+ cardbus_disable_retry(cc, cf, csc->sc_tag);
+ ath_resume(&csc->sc_ath);
+
+ return true;
+}
int
ath_cardbus_match(struct device *parent, struct cfdata *match,
@@ -161,13 +172,6 @@ ath_cardbus_attach(struct device *parent, struct device *self,
*/
sc->sc_enable = ath_cardbus_enable;
sc->sc_disable = ath_cardbus_disable;
- sc->sc_power = ath_cardbus_power;
-
- csc->sc_sdhook = shutdownhook_establish(ath_cardbus_shutdown, csc);
- if (csc->sc_sdhook == NULL) {
- aprint_error("couldn't establish shutdown hook\n");
- return;
- }
/*
* Map the device.
@@ -184,7 +188,6 @@ ath_cardbus_attach(struct device *parent, struct device *self,
else {
printf("%s: unable to map device registers\n",
sc->sc_dev.dv_xname);
- shutdownhook_disestablish(csc->sc_sdhook);
return;
}
@@ -199,15 +202,15 @@ ath_cardbus_attach(struct device *parent, struct device *self,
/* Remember which interrupt line. */
csc->sc_intrline = ca->ca_intrline;
+ if (!pmf_device_register(self, NULL, ath_cardbus_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, &sc->sc_if);
+
/*
* Finish off the attach.
*/
ath_attach(PCI_PRODUCT(ca->ca_id), sc);
-
- /*
- * Power down the socket.
- */
- Cardbus_function_disable(csc->sc_ct);
}
int
@@ -223,12 +226,12 @@ ath_cardbus_detach(struct device *self, int flags)
panic("%s: data structure lacks", sc->sc_dev.dv_xname);
#endif
- shutdownhook_disestablish(csc->sc_sdhook);
-
rv = ath_detach(sc);
if (rv)
return (rv);
+ pmf_device_deregister(self);
+
/*
* Unhook the interrupt handler.
*/
@@ -245,16 +248,6 @@ ath_cardbus_detach(struct device *self, int flags)
return (0);
}
-void
-ath_cardbus_shutdown(void *arg)
-{
- struct ath_cardbus_softc *csc;
-
- csc = arg;
-
- ath_shutdown(&csc->sc_ath);
-}
-
int
ath_cardbus_enable(struct ath_softc *sc)
{
@@ -301,44 +294,20 @@ ath_cardbus_disable(struct ath_softc *sc)
/* Unhook the interrupt handler. */
cardbus_intr_disestablish(cc, cf, csc->sc_ih);
csc->sc_ih = NULL;
-
- /* Power down the socket. */
- Cardbus_function_disable(ct);
-}
-
-void
-ath_cardbus_power(struct ath_softc *sc, int why)
-{
- struct ath_cardbus_softc *csc = (void *) sc;
-
- printf("%s: ath_cardbus_power\n", sc->sc_dev.dv_xname);
-
- if (why == PWR_RESUME) {
- /*
- * Give the PCI configuration registers a kick
- * in the head.
- */
-#ifdef DIAGNOSTIC
- if (ATH_IS_ENABLED(sc) == 0)
- panic("ath_cardbus_power");
-#endif
- ath_cardbus_setup(csc);
- }
}
void
ath_cardbus_setup(struct ath_cardbus_softc *csc)
{
- struct ath_softc *sc = &csc->sc_ath;
cardbus_devfunc_t ct = csc->sc_ct;
cardbus_chipset_tag_t cc = ct->ct_cc;
cardbus_function_tag_t cf = ct->ct_cf;
int error;
pcireg_t reg;
- if ((error = cardbus_setpowerstate(sc->sc_dev.dv_xname, ct, csc->sc_tag,
+ if ((error = cardbus_set_powerstate(ct, csc->sc_tag,
PCI_PWR_D0)) != 0)
- aprint_debug("%s: cardbus_setpowerstate %d\n", __func__, error);
+ aprint_debug("%s: cardbus_set_powerstate %d\n", __func__, error);
/* Program the BAR. */
cardbus_conf_write(cc, cf, csc->sc_tag, ATH_PCI_MMBA,
diff --git a/sys/dev/cardbus/if_atw_cardbus.c b/sys/dev/cardbus/if_atw_cardbus.c
index 16f5338c082..c65bc2e4245 100644
--- a/sys/dev/cardbus/if_atw_cardbus.c
+++ b/sys/dev/cardbus/if_atw_cardbus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_atw_cardbus.c,v 1.18 2007/10/19 11:59:38 ad Exp $ */
+/* $NetBSD: if_atw_cardbus.c,v 1.19 2007/12/09 20:27:56 jmcneill Exp $ */
/*-
* Copyright (c) 1999, 2000, 2003 The NetBSD Foundation, Inc.
@@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_atw_cardbus.c,v 1.18 2007/10/19 11:59:38 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_atw_cardbus.c,v 1.19 2007/12/09 20:27:56 jmcneill Exp $");
#include "opt_inet.h"
#include "bpfilter.h"
@@ -400,14 +400,12 @@ atw_cardbus_power(struct atw_softc *sc, int why)
void
atw_cardbus_setup(struct atw_cardbus_softc *csc)
{
- struct atw_softc *sc = &csc->sc_atw;
cardbus_devfunc_t ct = csc->sc_ct;
cardbus_chipset_tag_t cc = ct->ct_cc;
cardbus_function_tag_t cf = ct->ct_cf;
pcireg_t reg;
- (void)cardbus_setpowerstate(sc->sc_dev.dv_xname, ct, csc->sc_tag,
- PCI_PWR_D0);
+ (void)cardbus_set_powerstate(ct, csc->sc_tag, PCI_PWR_D0);
/* Program the BAR. */
cardbus_conf_write(cc, cf, csc->sc_tag, csc->sc_bar_reg,
diff --git a/sys/dev/cardbus/if_ex_cardbus.c b/sys/dev/cardbus/if_ex_cardbus.c
index f9a7af5a51f..43ffbea5cbe 100644
--- a/sys/dev/cardbus/if_ex_cardbus.c
+++ b/sys/dev/cardbus/if_ex_cardbus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ex_cardbus.c,v 1.40 2007/10/19 11:59:38 ad Exp $ */
+/* $NetBSD: if_ex_cardbus.c,v 1.41 2007/12/09 20:27:56 jmcneill Exp $ */
/*
* CardBus specific routines for 3Com 3C575-family CardBus ethernet adapter
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ex_cardbus.c,v 1.40 2007/10/19 11:59:38 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ex_cardbus.c,v 1.41 2007/12/09 20:27:56 jmcneill Exp $");
/* #define EX_DEBUG 4 */ /* define to report information for debugging */
@@ -413,14 +413,12 @@ void
ex_cardbus_setup(csc)
struct ex_cardbus_softc *csc;
{
- struct ex_softc *sc = &csc->sc_softc;
cardbus_devfunc_t ct = csc->sc_ct;
cardbus_chipset_tag_t cc = ct->ct_cc;
cardbus_function_tag_t cf = ct->ct_cf;
cardbusreg_t reg;
- (void)cardbus_setpowerstate(sc->sc_dev.dv_xname, ct, csc->sc_tag,
- PCI_PWR_D0);
+ (void)cardbus_set_powerstate(ct, csc->sc_tag, PCI_PWR_D0);
/* Program the BAR */
cardbus_conf_write(cc, cf, csc->sc_tag,
diff --git a/sys/dev/cardbus/if_ral_cardbus.c b/sys/dev/cardbus/if_ral_cardbus.c
index 1ed918966f9..adbb743b64a 100644
--- a/sys/dev/cardbus/if_ral_cardbus.c
+++ b/sys/dev/cardbus/if_ral_cardbus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ral_cardbus.c,v 1.9 2007/10/19 11:59:39 ad Exp $ */
+/* $NetBSD: if_ral_cardbus.c,v 1.10 2007/12/09 20:27:56 jmcneill Exp $ */
/* $OpenBSD: if_ral_cardbus.c,v 1.6 2006/01/09 20:03:31 damien Exp $ */
/*-
@@ -22,7 +22,7 @@
* CardBus front-end for the Ralink RT2560/RT2561/RT2561S/RT2661 driver.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ral_cardbus.c,v 1.9 2007/10/19 11:59:39 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ral_cardbus.c,v 1.10 2007/12/09 20:27:56 jmcneill Exp $");
#include "bpfilter.h"
@@ -148,7 +148,6 @@ ral_cardbus_attach(struct device *parent, struct device *self,
/* power management hooks */
sc->sc_enable = ral_cardbus_enable;
sc->sc_disable = ral_cardbus_disable;
- sc->sc_power = ral_cardbus_power;
/* map control/status registers */
error = Cardbus_mapreg_map(ct, CARDBUS_BASE0_REG,
@@ -247,22 +246,6 @@ ral_cardbus_disable(struct rt2560_softc *sc)
}
void
-ral_cardbus_power(struct rt2560_softc *sc, int why)
-{
-
- switch (why) {
- case PWR_RESUME:
- ral_cardbus_enable(sc);
- break;
- case PWR_SUSPEND:
- ral_cardbus_disable(sc);
- break;
- }
-
- return;
-}
-
-void
ral_cardbus_setup(struct ral_cardbus_softc *csc)
{
cardbus_devfunc_t ct = csc->sc_ct;
diff --git a/sys/dev/cardbus/if_re_cardbus.c b/sys/dev/cardbus/if_re_cardbus.c
index 3b0724a50d4..9b1cdba24f0 100644
--- a/sys/dev/cardbus/if_re_cardbus.c
+++ b/sys/dev/cardbus/if_re_cardbus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_re_cardbus.c,v 1.14 2007/10/19 11:59:39 ad Exp $ */
+/* $NetBSD: if_re_cardbus.c,v 1.15 2007/12/09 20:27:56 jmcneill Exp $ */
/*
* Copyright (c) 2004 Jonathan Stone
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_re_cardbus.c,v 1.14 2007/10/19 11:59:39 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_re_cardbus.c,v 1.15 2007/12/09 20:27:56 jmcneill Exp $");
#include "opt_inet.h"
#include "bpfilter.h"
@@ -133,7 +133,6 @@ void re_cardbus_setup(struct re_cardbus_softc *);
int re_cardbus_enable(struct rtk_softc *);
void re_cardbus_disable(struct rtk_softc *);
-void re_cardbus_power(struct rtk_softc *, int);
const struct rtk_type *
re_cardbus_lookup(const struct cardbus_attach_args *ca)
@@ -188,7 +187,6 @@ re_cardbus_attach(struct device *parent, struct device *self, void *aux)
*/
sc->sc_enable = re_cardbus_enable;
sc->sc_disable = re_cardbus_disable;
- sc->sc_power = re_cardbus_power;
/*
* Map control/status registers.
@@ -233,6 +231,11 @@ re_cardbus_attach(struct device *parent, struct device *self, void *aux)
sc->sc_dmat = ca->ca_dmat;
re_attach(sc);
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, &sc->ethercom.ec_if);
+
/*
* Power down the socket.
*/
@@ -252,9 +255,13 @@ re_cardbus_detach(struct device *self, int flags)
panic("%s: cardbus softc, cardbus_devfunc NULL",
sc->sc_dev.dv_xname);
#endif
+
rv = re_detach(sc);
if (rv)
return rv;
+
+ pmf_device_deregister(self);
+
/*
* Unhook the interrupt handler.
*/
@@ -394,21 +401,3 @@ re_cardbus_disable(struct rtk_softc *sc)
/* Power down the socket. */
Cardbus_function_disable(ct);
}
-
-void
-re_cardbus_power(struct rtk_softc *sc, int why)
-{
- struct re_cardbus_softc *csc = (void *) sc;
-
- if (why == PWR_RESUME) {
- /*
- * Give the PCI configuration registers a kick
- * in the head.
- */
-#ifdef DIAGNOSTIC
- if (RTK_IS_ENABLED(sc) == 0)
- panic("re_cardbus_power");
-#endif
- re_cardbus_setup(csc);
- }
-}
diff --git a/sys/dev/cardbus/if_rtk_cardbus.c b/sys/dev/cardbus/if_rtk_cardbus.c
index 9e3f843a165..166e1390e60 100644
--- a/sys/dev/cardbus/if_rtk_cardbus.c
+++ b/sys/dev/cardbus/if_rtk_cardbus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_rtk_cardbus.c,v 1.33 2007/10/19 11:59:39 ad Exp $ */
+/* $NetBSD: if_rtk_cardbus.c,v 1.34 2007/12/09 20:27:56 jmcneill Exp $ */
/*
* Copyright (c) 2000 Masanori Kanaoka
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_rtk_cardbus.c,v 1.33 2007/10/19 11:59:39 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_rtk_cardbus.c,v 1.34 2007/12/09 20:27:56 jmcneill Exp $");
#include "opt_inet.h"
#include "bpfilter.h"
@@ -206,7 +206,6 @@ rtk_cardbus_attach(struct device *parent, struct device *self,
*/
sc->sc_enable = rtk_cardbus_enable;
sc->sc_disable = rtk_cardbus_disable;
- sc->sc_power = rtk_cardbus_power;
/*
* Map control/status registers.
@@ -250,6 +249,11 @@ rtk_cardbus_attach(struct device *parent, struct device *self,
rtk_attach(sc);
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, &sc->ethercom.ec_if);
+
/*
* Power down the socket.
*/
@@ -413,23 +417,3 @@ rtk_cardbus_disable(sc)
/* Power down the socket. */
Cardbus_function_disable(ct);
}
-
-void
-rtk_cardbus_power(sc, why)
- struct rtk_softc *sc;
- int why;
-{
- struct rtk_cardbus_softc *csc = (void *) sc;
-
- if (why == PWR_RESUME) {
- /*
- * Give the PCI configuration registers a kick
- * in the head.
- */
-#ifdef DIAGNOSTIC
- if (RTK_IS_ENABLED(sc) == 0)
- panic("rtk_cardbus_power");
-#endif
- rtk_cardbus_setup(csc);
- }
-}
diff --git a/sys/dev/cardbus/if_rtw_cardbus.c b/sys/dev/cardbus/if_rtw_cardbus.c
index cde48f8d9da..d23df1a05e3 100644
--- a/sys/dev/cardbus/if_rtw_cardbus.c
+++ b/sys/dev/cardbus/if_rtw_cardbus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_rtw_cardbus.c,v 1.18 2007/11/16 18:47:41 dyoung Exp $ */
+/* $NetBSD: if_rtw_cardbus.c,v 1.19 2007/12/09 20:27:56 jmcneill Exp $ */
/*-
* Copyright (c) 2004, 2005 David Young. All rights reserved.
@@ -74,7 +74,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_rtw_cardbus.c,v 1.18 2007/11/16 18:47:41 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_rtw_cardbus.c,v 1.19 2007/12/09 20:27:56 jmcneill Exp $");
#include "opt_inet.h"
#include "bpfilter.h"
@@ -464,15 +464,13 @@ rtw_cardbus_power(struct rtw_softc *sc, int why)
void
rtw_cardbus_setup(struct rtw_cardbus_softc *csc)
{
- struct rtw_softc *sc = &csc->sc_rtw;
cardbustag_t tag = csc->sc_tag;
cardbus_devfunc_t ct = csc->sc_ct;
cardbus_chipset_tag_t cc = ct->ct_cc;
cardbusreg_t bhlc, csr, lattimer;
cardbus_function_tag_t cf = ct->ct_cf;
- (void)cardbus_setpowerstate(device_xname(&sc->sc_dev), ct, tag,
- PCI_PWR_D0);
+ (void)cardbus_set_powerstate(ct, tag, PCI_PWR_D0);
/* I believe the datasheet tries to warn us that the RTL8180
* wants for 16 (0x10) to divide the latency timer.
diff --git a/sys/dev/cardbus/if_tlp_cardbus.c b/sys/dev/cardbus/if_tlp_cardbus.c
index e388c8150b5..6d90b018999 100644
--- a/sys/dev/cardbus/if_tlp_cardbus.c
+++ b/sys/dev/cardbus/if_tlp_cardbus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_tlp_cardbus.c,v 1.54 2007/10/19 11:59:39 ad Exp $ */
+/* $NetBSD: if_tlp_cardbus.c,v 1.55 2007/12/09 20:27:56 jmcneill Exp $ */
/*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_tlp_cardbus.c,v 1.54 2007/10/19 11:59:39 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_tlp_cardbus.c,v 1.55 2007/12/09 20:27:56 jmcneill Exp $");
#include "opt_inet.h"
#include "bpfilter.h"
@@ -612,8 +612,7 @@ tlp_cardbus_setup(csc)
break;
}
- (void)cardbus_setpowerstate(sc->sc_dev.dv_xname, ct, csc->sc_tag,
- PCI_PWR_D0);
+ (void)cardbus_set_powerstate(ct, csc->sc_tag, PCI_PWR_D0);
/* Program the BAR. */
cardbus_conf_write(cc, cf, csc->sc_tag, csc->sc_bar_reg,
diff --git a/sys/dev/dkwedge/dk.c b/sys/dev/dkwedge/dk.c
index 9c4fd442c99..932682a9b5d 100644
--- a/sys/dev/dkwedge/dk.c
+++ b/sys/dev/dkwedge/dk.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dk.c,v 1.30 2007/11/26 19:01:37 pooka Exp $ */
+/* $NetBSD: dk.c,v 1.31 2007/12/09 20:27:56 jmcneill Exp $ */
/*-
* Copyright (c) 2004, 2005, 2006, 2007 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dk.c,v 1.30 2007/11/26 19:01:37 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dk.c,v 1.31 2007/12/09 20:27:56 jmcneill Exp $");
#include "opt_dkwedge.h"
@@ -150,7 +150,8 @@ dkwedge_attach(struct device *parent, struct device *self,
void *aux)
{
- /* Nothing to do. */
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
/*
@@ -162,6 +163,7 @@ static int
dkwedge_detach(struct device *self, int flags)
{
+ pmf_device_deregister(self);
/* Always succeeds. */
return (0);
}
diff --git a/sys/dev/i2c/i2c.c b/sys/dev/i2c/i2c.c
index bef090b4481..3c7dc60c8d6 100644
--- a/sys/dev/i2c/i2c.c
+++ b/sys/dev/i2c/i2c.c
@@ -1,4 +1,4 @@
-/* $NetBSD: i2c.c,v 1.16 2007/11/12 19:42:44 joerg Exp $ */
+/* $NetBSD: i2c.c,v 1.17 2007/12/09 20:27:57 jmcneill Exp $ */
/*
* Copyright (c) 2003 Wasabi Systems, Inc.
@@ -152,6 +152,9 @@ iic_attach(struct device *parent, struct device *self, void *aux)
}
#endif
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
/*
* Attach all i2c devices described in the kernel
* configuration file.
diff --git a/sys/dev/ic/an.c b/sys/dev/ic/an.c
index 85274e44824..8c5da46371c 100644
--- a/sys/dev/ic/an.c
+++ b/sys/dev/ic/an.c
@@ -1,4 +1,4 @@
-/* $NetBSD: an.c,v 1.49 2007/10/19 11:59:47 ad Exp $ */
+/* $NetBSD: an.c,v 1.50 2007/12/09 20:27:57 jmcneill Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
@@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: an.c,v 1.49 2007/10/19 11:59:47 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: an.c,v 1.50 2007/12/09 20:27:57 jmcneill Exp $");
#include "bpfilter.h"
@@ -448,41 +448,6 @@ an_activate(struct device *self, enum devact act)
return error;
}
-void
-an_power(int why, void *arg)
-{
- int s;
- struct an_softc *sc = arg;
- struct ifnet *ifp = &sc->sc_if;
-
- s = splnet();
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- an_stop(ifp, 1);
- break;
- case PWR_RESUME:
- if (ifp->if_flags & IFF_UP) {
- an_init(ifp);
- (void)an_intr(sc);
- }
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
- }
- splx(s);
-}
-
-void
-an_shutdown(struct an_softc *sc)
-{
-
- if (sc->sc_attached)
- an_stop(&sc->sc_if, 1);
-}
-
int
an_intr(void *arg)
{
diff --git a/sys/dev/ic/anvar.h b/sys/dev/ic/anvar.h
index eb0be9d34f3..b0f931f0d3e 100644
--- a/sys/dev/ic/anvar.h
+++ b/sys/dev/ic/anvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: anvar.h,v 1.14 2007/03/04 06:01:49 christos Exp $ */
+/* $NetBSD: anvar.h,v 1.15 2007/12/09 20:27:57 jmcneill Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
@@ -165,8 +165,6 @@ struct an_softc {
int an_attach(struct an_softc *);
int an_detach(struct an_softc *);
int an_activate(struct device *, enum devact);
-void an_power(int, void *);
-void an_shutdown(struct an_softc *);
int an_intr(void *);
#endif /* _DEV_IC_ANVAR_H */
diff --git a/sys/dev/ic/ath.c b/sys/dev/ic/ath.c
index d5d8a15db92..57ff814bf43 100644
--- a/sys/dev/ic/ath.c
+++ b/sys/dev/ic/ath.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ath.c,v 1.92 2007/11/27 00:07:42 dyoung Exp $ */
+/* $NetBSD: ath.c,v 1.93 2007/12/09 20:27:57 jmcneill Exp $ */
/*-
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
@@ -41,7 +41,7 @@
__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.104 2005/09/16 10:09:23 ru Exp $");
#endif
#ifdef __NetBSD__
-__KERNEL_RCSID(0, "$NetBSD: ath.c,v 1.92 2007/11/27 00:07:42 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ath.c,v 1.93 2007/12/09 20:27:57 jmcneill Exp $");
#endif
/*
@@ -203,7 +203,6 @@ static void ath_setcurmode(struct ath_softc *, enum ieee80211_phymode);
#ifdef __NetBSD__
int ath_enable(struct ath_softc *);
void ath_disable(struct ath_softc *);
-void ath_power(int, void *);
#endif
#if NBPFILTER > 0
@@ -526,6 +525,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
ifp->if_softc = sc;
ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
ifp->if_start = ath_start;
+ ifp->if_stop = ath_stop;
ifp->if_watchdog = ath_watchdog;
ifp->if_ioctl = ath_ioctl;
ifp->if_init = ath_ifinit;
@@ -639,14 +639,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
ath_bpfattach(sc);
#endif
-#ifdef __NetBSD__
sc->sc_flags |= ATH_ATTACHED;
- sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- ath_power, sc);
- if (sc->sc_powerhook == NULL)
- printf("%s: WARNING: unable to establish power hook\n",
- sc->sc_dev.dv_xname);
-#endif
/*
* Setup dynamic sysctl's now that country code and
@@ -713,78 +706,15 @@ ath_detach(struct ath_softc *sc)
return 0;
}
-#ifdef __NetBSD__
-void
-ath_power(int why, void *arg)
-{
- struct ath_softc *sc = arg;
- int s;
-
- DPRINTF(sc, ATH_DEBUG_ANY, "ath_power(%d)\n", why);
-
- s = splnet();
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- ath_suspend(sc, why);
- break;
- case PWR_RESUME:
- ath_resume(sc, why);
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
- }
- splx(s);
-}
-#endif
-
-void
-ath_suspend(struct ath_softc *sc, int why)
-{
- struct ifnet *ifp = &sc->sc_if;
-
- DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags %x\n",
- __func__, ifp->if_flags);
-
- ath_stop(ifp, 1);
- if (sc->sc_power != NULL)
- (*sc->sc_power)(sc, why);
-}
-
void
-ath_resume(struct ath_softc *sc, int why)
+ath_resume(struct ath_softc *sc)
{
- struct ifnet *ifp = &sc->sc_if;
-
- DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags %x\n",
- __func__, ifp->if_flags);
-
- if (ifp->if_flags & IFF_UP) {
- ath_init(sc);
-#if 0
- (void)ath_intr(sc);
-#endif
- if (sc->sc_power != NULL)
- (*sc->sc_power)(sc, why);
- if (ifp->if_flags & IFF_RUNNING)
- ath_start(ifp);
- }
if (sc->sc_softled) {
ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_ledpin);
ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, !sc->sc_ledon);
}
}
-void
-ath_shutdown(void *arg)
-{
- struct ath_softc *sc = arg;
-
- ath_stop(&sc->sc_if, 1);
-}
-
/*
* Interrupt handler. Most of the actual processing is deferred.
*/
diff --git a/sys/dev/ic/athvar.h b/sys/dev/ic/athvar.h
index 783387b0eb4..e34bf253896 100644
--- a/sys/dev/ic/athvar.h
+++ b/sys/dev/ic/athvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: athvar.h,v 1.21 2007/07/17 01:26:17 dyoung Exp $ */
+/* $NetBSD: athvar.h,v 1.22 2007/12/09 20:27:57 jmcneill Exp $ */
/*-
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
@@ -306,11 +306,8 @@ struct ath_softc {
int ath_attach(u_int16_t, struct ath_softc *);
int ath_detach(struct ath_softc *);
-void ath_resume(struct ath_softc *, int);
-void ath_suspend(struct ath_softc *, int);
int ath_activate(struct device *, enum devact);
-void ath_power(int, void *);
-void ath_shutdown(void *);
+void ath_resume(struct ath_softc *);
int ath_intr(void *);
int ath_reset(struct ifnet *);
void ath_sysctlattach(struct ath_softc *);
diff --git a/sys/dev/ic/attimer.c b/sys/dev/ic/attimer.c
index 413a09b3603..f78aade6e87 100644
--- a/sys/dev/ic/attimer.c
+++ b/sys/dev/ic/attimer.c
@@ -1,4 +1,4 @@
-/* $NetBSD: attimer.c,v 1.4 2007/10/19 11:59:48 ad Exp $ */
+/* $NetBSD: attimer.c,v 1.5 2007/12/09 20:27:58 jmcneill Exp $ */
/*
* Copyright (c) 2005 The NetBSD Foundation.
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: attimer.c,v 1.4 2007/10/19 11:59:48 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: attimer.c,v 1.5 2007/12/09 20:27:58 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -56,6 +56,9 @@ void
attimer_attach(struct attimer_softc *sc)
{
sc->sc_flags |= ATT_CONFIGURED;
+
+ if (!pmf_device_register(&sc->sc_dev, NULL, NULL))
+ aprint_error_dev(&sc->sc_dev, "couldn't establish power handler\n");
}
/*
diff --git a/sys/dev/ic/hpet.c b/sys/dev/ic/hpet.c
index 0794eb1b974..9b22e4d0e75 100644
--- a/sys/dev/ic/hpet.c
+++ b/sys/dev/ic/hpet.c
@@ -1,4 +1,4 @@
-/* $NetBSD: hpet.c,v 1.3 2007/12/01 16:51:22 ad Exp $ */
+/* $NetBSD: hpet.c,v 1.4 2007/12/09 20:27:58 jmcneill Exp $ */
/*
* Copyright (c) 2006 Nicolas Joly
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hpet.c,v 1.3 2007/12/01 16:51:22 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hpet.c,v 1.4 2007/12/09 20:27:58 jmcneill Exp $");
#include <sys/systm.h>
#include <sys/device.h>
@@ -48,6 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: hpet.c,v 1.3 2007/12/01 16:51:22 ad Exp $");
#include <dev/ic/hpetvar.h>
static u_int hpet_get_timecount(struct timecounter *);
+static bool hpet_resume(device_t);
void
hpet_attach_subr(struct hpet_softc *sc) {
@@ -60,12 +61,6 @@ hpet_attach_subr(struct hpet_softc *sc) {
tc->tc_get_timecount = hpet_get_timecount;
tc->tc_quality = 2000;
- /* XXX Only 32-bits supported for now */
- val = bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_INFO);
- if ((val & HPET_INFO_64BITS) != 0) {
- aprint_debug("%s: Found 64-bits HPET, will only use lowest"
- " 32-bits\n", sc->sc_dev.dv_xname);
- }
tc->tc_counter_mask = 0xffffffff;
/* Get frequency */
@@ -81,12 +76,27 @@ hpet_attach_subr(struct hpet_softc *sc) {
tc->tc_priv = sc;
tc_init(tc);
+
+ if (!pmf_device_register(&sc->sc_dev, NULL, hpet_resume))
+ aprint_error_dev(&sc->sc_dev, "couldn't establish power handler\n");
}
static u_int
hpet_get_timecount(struct timecounter *tc) {
struct hpet_softc *sc = tc->tc_priv;
- return bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_MCOUNT);
+ return bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_MCOUNT_LO);
}
+static bool
+hpet_resume(device_t dv)
+{
+ struct hpet_softc *sc = device_private(dv);
+ uint32_t val;
+
+ val = bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_CONFIG);
+ val |= HPET_CONFIG_ENABLE;
+ bus_space_write_4(sc->sc_memt, sc->sc_memh, HPET_CONFIG, val);
+
+ return true;
+}
diff --git a/sys/dev/ic/hpetreg.h b/sys/dev/ic/hpetreg.h
index 16648a20bf1..dcde6ee447a 100644
--- a/sys/dev/ic/hpetreg.h
+++ b/sys/dev/ic/hpetreg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: hpetreg.h,v 1.1 2007/03/08 14:26:28 njoly Exp $ */
+/* $NetBSD: hpetreg.h,v 1.2 2007/12/09 20:27:58 jmcneill Exp $ */
/*
* Copyright (c) 2006 Nicolas Joly
@@ -31,11 +31,27 @@
#ifndef _DEV_IC_HPETREG_H_
#define _DEV_IC_HPETREG_H_
-#define HPET_INFO 0x00
-#define HPET_INFO_64BITS 0x2000
-#define HPET_PERIOD 0x04
-#define HPET_CONFIG 0x10
-#define HPET_CONFIG_ENABLE 0x0001
-#define HPET_MCOUNT 0xf0
+#define HPET_WINDOW_SIZE 0x400
+
+#define HPET_INFO 0x00
+#define HPET_INFO_64BITS 0x2000
+#define HPET_PERIOD 0x04
+#define HPET_CONFIG 0x10
+#define HPET_CONFIG_ENABLE 0x0001
+#define HPET_MCOUNT_LO 0xf0
+#define HPET_MCOUNT_HI 0xf4
+#define HPET_INT_STATUS 0x20
+#define HPET_INT_STS_TIMER0 0x00000001
+
+#define HPET_TIMER_USE_LEVEL_INTR 0x00000002
+#define HPET_TIMER_ENABLE_INTR 0x00000004
+#define HPET_TIMER_IS_PERIODIC_INTR 0x00000008
+#define HPET_TIMER_HAS_PERIODIC_INTR 0x00000010
+#define HPET_TIMER_INTR_SHIFT 9
+
+#define HPET_TIMER0_CONFIG 0x0100
+#define HPET_TIMER0_INTCAP 0x0104
+#define HPET_TIMER0_CMPREG_LO 0x0108
+#define HPET_TIMER0_CMPREG_HI 0x010C
#endif /* _DEV_IC_HPETREG_H_ */
diff --git a/sys/dev/ic/i82801lpcreg.h b/sys/dev/ic/i82801lpcreg.h
index c2cfbe2f86c..ddddbc28418 100644
--- a/sys/dev/ic/i82801lpcreg.h
+++ b/sys/dev/ic/i82801lpcreg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: i82801lpcreg.h,v 1.6 2007/08/26 18:39:43 xtraeme Exp $ */
+/* $NetBSD: i82801lpcreg.h,v 1.7 2007/12/09 20:27:58 jmcneill Exp $ */
/*-
* Copyright (c) 2004 The NetBSD Foundation, Inc.
@@ -78,6 +78,16 @@
#define LPCIB_PCI_MON7_TRP_RNG 0xc7
#define LPCIB_PCI_MON_TRP_MSK oxcc
#define LPCIB_PCI_GEN_CNTL 0xd0
+#define LPCIB_ICH5_HPTC_EN 0x00020000
+#define LPCIB_ICH5_HPTC_WIN_MASK 0x0000c000
+#define LPCIB_ICH5_HPTC_0000 0x00000000
+#define LPCIB_ICH5_HPTC_0000_BASE 0xfed00000
+#define LPCIB_ICH5_HPTC_1000 0x00008000
+#define LPCIB_ICH5_HPTC_1000_BASE 0xfed01000
+#define LPCIB_ICH5_HPTC_2000 0x00010000
+#define LPCIB_ICH5_HPTC_2000_BASE 0xfed02000
+#define LPCIB_ICH5_HPTC_3000 0x00018000
+#define LPCIB_ICH5_HPTC_3000_BASE 0xfed03000
#define LPCIB_PCI_GEN_STA 0xd4
# define LPCIB_PCI_GEN_STA_SAFE_MODE (1 << 2)
# define LPCIB_PCI_GEN_STA_NO_REBOOT (1 << 1)
@@ -209,9 +219,21 @@
/* ICH Chipset Configuration Registers (ICH6 and newer) */
#define LPCIB_RCBA 0xf0
-#define LPCIB_GCS_OFFSET 0x3410
-#define LPCIB_GCS_SIZE 4
-#define LPCIB_GCS_NO_REBOOT 0x20
+#define LPCIB_RCBA_EN 0x00000001
+#define LPCIB_RCBA_SIZE 0x00004000
+#define LPCIB_GCS_OFFSET 0x3410
+#define LPCIB_GCS_NO_REBOOT 0x20
+#define LPCIB_RCBA_HPTC 0x00003404
+#define LPCIB_RCBA_HPTC_EN 0x00000080
+#define LPCIB_RCBA_HPTC_WIN_MASK 0x00000003
+#define LPCIB_RCBA_HPTC_0000 0x00000000
+#define LPCIB_RCBA_HPTC_0000_BASE 0xfed00000
+#define LPCIB_RCBA_HPTC_1000 0x00000001
+#define LPCIB_RCBA_HPTC_1000_BASE 0xfed01000
+#define LPCIB_RCBA_HPTC_2000 0x00000002
+#define LPCIB_RCBA_HPTC_2000_BASE 0xfed02000
+#define LPCIB_RCBA_HPTC_3000 0x00000003
+#define LPCIB_RCBA_HPTC_3000_BASE 0xfed03000
/*
* System management TCO registers
diff --git a/sys/dev/ic/pckbc.c b/sys/dev/ic/pckbc.c
index bf1ce784220..ed39bd94af1 100644
--- a/sys/dev/ic/pckbc.c
+++ b/sys/dev/ic/pckbc.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pckbc.c,v 1.38 2007/10/19 11:59:59 ad Exp $ */
+/* $NetBSD: pckbc.c,v 1.39 2007/12/09 20:27:58 jmcneill Exp $ */
/*
* Copyright (c) 2004 Ben Harris.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pckbc.c,v 1.38 2007/10/19 11:59:59 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pckbc.c,v 1.39 2007/12/09 20:27:58 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -714,3 +714,20 @@ pckbc_cnattach(iot, addr, cmd_offset, slot)
return (res);
}
+
+bool
+pckbc_resume(device_t dv)
+{
+ struct pckbc_softc *sc = device_private(dv);
+ struct pckbc_internal *t;
+
+ t = sc->id;
+ (void)pckbc_poll_data1(t, PCKBC_KBD_SLOT);
+ if (!pckbc_send_cmd(t->t_iot, t->t_ioh_c, KBC_SELFTEST))
+ return false;
+ (void)pckbc_poll_data1(t, PCKBC_KBD_SLOT);
+ (void)pckbc_put8042cmd(t);
+ pckbcintr(t->t_sc);
+
+ return true;
+}
diff --git a/sys/dev/ic/pckbcvar.h b/sys/dev/ic/pckbcvar.h
index aac2d483393..0288621ed07 100644
--- a/sys/dev/ic/pckbcvar.h
+++ b/sys/dev/ic/pckbcvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: pckbcvar.h,v 1.12 2005/12/11 12:21:28 christos Exp $ */
+/* $NetBSD: pckbcvar.h,v 1.13 2007/12/09 20:27:58 jmcneill Exp $ */
/*
* Copyright (c) 1998
@@ -111,4 +111,7 @@ void pckbcintr_soft(void *);
/* md hook for use without mi wscons */
int pckbc_machdep_cnattach(pckbc_tag_t, pckbc_slot_t);
+/* power management */
+bool pckbc_resume(device_t);
+
#endif /* _DEV_IC_PCKBCVAR_H_ */
diff --git a/sys/dev/ic/rt2560.c b/sys/dev/ic/rt2560.c
index 7cdca7ae351..a21b62ef31b 100644
--- a/sys/dev/ic/rt2560.c
+++ b/sys/dev/ic/rt2560.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rt2560.c,v 1.14 2007/10/21 17:03:37 degroote Exp $ */
+/* $NetBSD: rt2560.c,v 1.15 2007/12/09 20:27:58 jmcneill Exp $ */
/* $OpenBSD: rt2560.c,v 1.15 2006/04/20 20:31:12 miod Exp $ */
/* $FreeBSD: rt2560.c,v 1.3 2006/03/21 21:15:43 damien Exp $*/
@@ -24,7 +24,7 @@
* http://www.ralinktech.com/
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rt2560.c,v 1.14 2007/10/21 17:03:37 degroote Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rt2560.c,v 1.15 2007/12/09 20:27:58 jmcneill Exp $");
#include "bpfilter.h"
@@ -148,8 +148,7 @@ static const char *rt2560_get_rf(int);
static void rt2560_read_eeprom(struct rt2560_softc *);
static int rt2560_bbp_init(struct rt2560_softc *);
static int rt2560_init(struct ifnet *);
-static void rt2560_stop(void *);
-static void rt2560_powerhook(int, void *);
+static void rt2560_stop(struct ifnet *, int);
/*
* Supported rates for 802.11a/b/g modes (in 500Kbps unit).
@@ -401,16 +400,10 @@ rt2560_attach(void *xsc, int id)
goto fail5;
}
- sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- rt2560_powerhook, sc);
- if (sc->sc_powerhook == NULL)
- aprint_error("%s: can't establish powerhook\n",
- sc->sc_dev.dv_xname);
- sc->sc_suspend = PWR_RESUME;
-
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_init = rt2560_init;
+ ifp->if_stop = rt2560_stop;
ifp->if_ioctl = rt2560_ioctl;
ifp->if_start = rt2560_start;
ifp->if_watchdog = rt2560_watchdog;
@@ -496,6 +489,11 @@ rt2560_attach(void *xsc, int id)
ieee80211_announce(ic);
+ if (!pmf_device_register(&sc->sc_dev, NULL, NULL))
+ aprint_error_dev(&sc->sc_dev, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(&sc->sc_dev, ifp);
+
return 0;
fail5: rt2560_free_tx_ring(sc, &sc->bcnq);
@@ -516,10 +514,9 @@ rt2560_detach(void *xsc)
callout_stop(&sc->scan_ch);
callout_stop(&sc->rssadapt_ch);
- if (sc->sc_powerhook != NULL)
- powerhook_disestablish(sc->sc_powerhook);
+ pmf_device_deregister(&sc->sc_dev);
- rt2560_stop(sc);
+ rt2560_stop(ifp, 1);
ieee80211_ifdetach(&sc->sc_ic); /* free all nodes */
if_detach(ifp);
@@ -1463,7 +1460,7 @@ rt2560_shutdown(void *xsc)
{
struct rt2560_softc *sc = xsc;
- rt2560_stop(sc);
+ rt2560_stop(&sc->sc_if, 1);
}
void
@@ -1471,7 +1468,7 @@ rt2560_suspend(void *xsc)
{
struct rt2560_softc *sc = xsc;
- rt2560_stop(sc);
+ rt2560_stop(&sc->sc_if, 1);
}
void
@@ -1534,6 +1531,9 @@ rt2560_intr(void *arg)
struct ifnet *ifp = &sc->sc_if;
uint32_t r;
+ if (!device_is_active(&sc->sc_dev))
+ return 0;
+
/* disable interrupts */
RAL_WRITE(sc, RT2560_CSR8, 0xffffffff);
@@ -1541,10 +1541,6 @@ rt2560_intr(void *arg)
if (!(ifp->if_flags & IFF_RUNNING))
return 0;
- /* if we're suspended, don't bother */
- if (sc->sc_suspend != PWR_RESUME)
- return 0;
-
r = RAL_READ(sc, RT2560_CSR7);
RAL_WRITE(sc, RT2560_CSR7, r);
@@ -2257,7 +2253,7 @@ rt2560_ioctl(struct ifnet *ifp, u_long cmd, void *data)
rt2560_init(ifp);
} else {
if (ifp->if_flags & IFF_RUNNING)
- rt2560_stop(sc);
+ rt2560_stop(ifp, 1);
}
break;
@@ -2819,7 +2815,7 @@ rt2560_init(struct ifnet *ifp)
sc->sc_flags |= RT2560_ENABLED;
}
- rt2560_stop(sc);
+ rt2560_stop(ifp, 1);
/* setup tx rings */
tmp = RT2560_PRIO_RING_COUNT << 24 |
@@ -2860,7 +2856,7 @@ rt2560_init(struct ifnet *ifp)
RAL_WRITE(sc, RT2560_CSR1, RT2560_HOST_READY);
if (rt2560_bbp_init(sc) != 0) {
- rt2560_stop(sc);
+ rt2560_stop(ifp, 1);
return EIO;
}
@@ -2902,11 +2898,10 @@ rt2560_init(struct ifnet *ifp)
}
static void
-rt2560_stop(void *priv)
+rt2560_stop(struct ifnet *ifp, int disable)
{
- struct rt2560_softc *sc = priv;
+ struct rt2560_softc *sc = ifp->if_softc;
struct ieee80211com *ic = &sc->sc_ic;
- struct ifnet *ifp = ic->ic_ifp;
sc->sc_tx_timer = 0;
ifp->if_timer = 0;
@@ -2938,41 +2933,3 @@ rt2560_stop(void *priv)
rt2560_reset_rx_ring(sc, &sc->rxq);
}
-
-static void
-rt2560_powerhook(int why, void *opaque)
-{
- struct rt2560_softc *sc;
- struct ifnet *ifp;
- int s;
-
- sc = (struct rt2560_softc *)opaque;
- ifp = &sc->sc_if;
-
- s = splnet();
- switch (why) {
- case PWR_SUSPEND:
- sc->sc_suspend = why;
- rt2560_stop(sc);
- if (sc->sc_power != NULL)
- (*sc->sc_power)(sc, why);
- break;
- case PWR_RESUME:
- sc->sc_suspend = why;
- if (ifp->if_flags & IFF_UP) {
- if (sc->sc_power != NULL)
- (*sc->sc_power)(sc, why);
- rt2560_init(ifp);
- if (ifp->if_flags & IFF_RUNNING)
- rt2560_start(ifp);
- }
- break;
- case PWR_STANDBY:
- case PWR_SOFTSUSPEND:
- case PWR_SOFTRESUME:
- break;
- }
- splx(s);
-
- return;
-}
diff --git a/sys/dev/ic/rt2560var.h b/sys/dev/ic/rt2560var.h
index a4183608eab..23acf28d946 100644
--- a/sys/dev/ic/rt2560var.h
+++ b/sys/dev/ic/rt2560var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rt2560var.h,v 1.5 2007/03/04 06:02:00 christos Exp $ */
+/* $NetBSD: rt2560var.h,v 1.6 2007/12/09 20:27:58 jmcneill Exp $ */
/* $OpenBSD: rt2560var.h,v 1.2 2006/01/14 12:43:27 damien Exp $ */
/*-
@@ -105,7 +105,6 @@ struct rt2560_softc {
int (*sc_enable)(struct rt2560_softc *);
void (*sc_disable)(struct rt2560_softc *);
- void (*sc_power)(struct rt2560_softc *, int);
bus_dma_tag_t sc_dmat;
bus_space_tag_t sc_st;
@@ -167,9 +166,6 @@ struct rt2560_softc {
#define sc_txtap sc_txtapu.th
int sc_txtap_len;
#endif
-
- void *sc_powerhook;
- int sc_suspend;
};
#define sc_if sc_ec.ec_if
diff --git a/sys/dev/ic/rt2661.c b/sys/dev/ic/rt2661.c
index f5b0e2d2cbc..06caca4c4bc 100644
--- a/sys/dev/ic/rt2661.c
+++ b/sys/dev/ic/rt2661.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rt2661.c,v 1.20 2007/10/21 17:03:37 degroote Exp $ */
+/* $NetBSD: rt2661.c,v 1.21 2007/12/09 20:27:58 jmcneill Exp $ */
/* $OpenBSD: rt2661.c,v 1.17 2006/05/01 08:41:11 damien Exp $ */
/* $FreeBSD: rt2560.c,v 1.5 2006/06/02 19:59:31 csjp Exp $ */
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rt2661.c,v 1.20 2007/10/21 17:03:37 degroote Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rt2661.c,v 1.21 2007/12/09 20:27:58 jmcneill Exp $");
#include "bpfilter.h"
@@ -427,6 +427,7 @@ rt2661_attach(void *xsc, int id)
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_init = rt2661_init;
+ ifp->if_stop = rt2661_stop;
ifp->if_ioctl = rt2661_ioctl;
ifp->if_start = rt2661_start;
ifp->if_watchdog = rt2661_watchdog;
@@ -509,6 +510,11 @@ rt2661_attach(void *xsc, int id)
ieee80211_announce(ic);
+ if (!pmf_device_register(&sc->sc_dev, NULL, NULL))
+ aprint_error_dev(&sc->sc_dev, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(&sc->sc_dev, ifp);
+
return 0;
fail6: rt2661_free_tx_ring(sc, &sc->mgtq);
@@ -528,6 +534,8 @@ rt2661_detach(void *xsc)
callout_stop(&sc->scan_ch);
callout_stop(&sc->rssadapt_ch);
+ pmf_device_deregister(&sc->sc_dev);
+
ieee80211_ifdetach(&sc->sc_ic);
if_detach(ifp);
diff --git a/sys/dev/ic/rt2661var.h b/sys/dev/ic/rt2661var.h
index 0e7221432f6..e754bbd72ec 100644
--- a/sys/dev/ic/rt2661var.h
+++ b/sys/dev/ic/rt2661var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rt2661var.h,v 1.6 2007/03/04 06:02:00 christos Exp $ */
+/* $NetBSD: rt2661var.h,v 1.7 2007/12/09 20:27:59 jmcneill Exp $ */
/* $OpenBSD: rt2661var.h,v 1.4 2006/02/25 12:56:47 damien Exp $ */
/*-
@@ -98,7 +98,6 @@ struct rt2661_softc {
int (*sc_enable)(struct rt2661_softc *);
void (*sc_disable)(struct rt2661_softc *);
- void (*sc_power)(struct rt2661_softc *, int);
bus_dma_tag_t sc_dmat;
bus_space_tag_t sc_st;
diff --git a/sys/dev/ic/rtl8169.c b/sys/dev/ic/rtl8169.c
index 1b6286e83b7..5459da14f8b 100644
--- a/sys/dev/ic/rtl8169.c
+++ b/sys/dev/ic/rtl8169.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rtl8169.c,v 1.89 2007/10/19 11:59:59 ad Exp $ */
+/* $NetBSD: rtl8169.c,v 1.90 2007/12/09 20:27:59 jmcneill Exp $ */
/*
* Copyright (c) 1997, 1998-2003
@@ -162,10 +162,8 @@ static int re_init(struct ifnet *);
static void re_stop(struct ifnet *, int);
static void re_watchdog(struct ifnet *);
-static void re_shutdown(void *);
static int re_enable(struct rtk_softc *);
static void re_disable(struct rtk_softc *);
-static void re_power(int, void *);
static int re_ifmedia_upd(struct ifnet *);
static void re_ifmedia_sts(struct ifnet *, struct ifmediareq *);
@@ -794,25 +792,6 @@ re_attach(struct rtk_softc *sc)
if_attach(ifp);
ether_ifattach(ifp, eaddr);
-
- /*
- * Make sure the interface is shutdown during reboot.
- */
- sc->sc_sdhook = shutdownhook_establish(re_shutdown, sc);
- if (sc->sc_sdhook == NULL)
- aprint_error("%s: WARNING: unable to establish shutdown hook\n",
- sc->sc_dev.dv_xname);
- /*
- * Add a suspend hook to make sure we come back up after a
- * resume.
- */
- sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- re_power, sc);
- if (sc->sc_powerhook == NULL)
- aprint_error("%s: WARNING: unable to establish power hook\n",
- sc->sc_dev.dv_xname);
-
-
return;
fail_8:
@@ -936,10 +915,6 @@ re_detach(struct rtk_softc *sc)
bus_dmamem_free(sc->sc_dmat,
&sc->re_ldata.re_tx_listseg, sc->re_ldata.re_tx_listnseg);
-
- shutdownhook_disestablish(sc->sc_sdhook);
- powerhook_disestablish(sc->sc_powerhook);
-
return 0;
}
@@ -976,41 +951,6 @@ re_disable(struct rtk_softc *sc)
}
}
-/*
- * re_power:
- * Power management (suspend/resume) hook.
- */
-void
-re_power(int why, void *arg)
-{
- struct rtk_softc *sc = (void *)arg;
- struct ifnet *ifp = &sc->ethercom.ec_if;
- int s;
-
- s = splnet();
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- re_stop(ifp, 0);
- if (sc->sc_power != NULL)
- (*sc->sc_power)(sc, why);
- break;
- case PWR_RESUME:
- if (ifp->if_flags & IFF_UP) {
- if (sc->sc_power != NULL)
- (*sc->sc_power)(sc, why);
- re_init(ifp);
- }
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
- }
- splx(s);
-}
-
-
static int
re_newbuf(struct rtk_softc *sc, int idx, struct mbuf *m)
{
@@ -1376,20 +1316,6 @@ re_txeof(struct rtk_softc *sc)
ifp->if_timer = 0;
}
-/*
- * Stop all chip I/O so that the kernel's probe routines don't
- * get confused by errant DMAs when rebooting.
- */
-static void
-re_shutdown(void *vsc)
-
-{
- struct rtk_softc *sc = vsc;
-
- re_stop(&sc->ethercom.ec_if, 0);
-}
-
-
static void
re_tick(void *xsc)
{
diff --git a/sys/dev/ic/rtl81x9.c b/sys/dev/ic/rtl81x9.c
index 524b1ec3a78..f38755c8e44 100644
--- a/sys/dev/ic/rtl81x9.c
+++ b/sys/dev/ic/rtl81x9.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rtl81x9.c,v 1.78 2007/11/06 02:29:20 uwe Exp $ */
+/* $NetBSD: rtl81x9.c,v 1.79 2007/12/09 20:27:59 jmcneill Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -86,7 +86,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rtl81x9.c,v 1.78 2007/11/06 02:29:20 uwe Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtl81x9.c,v 1.79 2007/12/09 20:27:59 jmcneill Exp $");
#include "bpfilter.h"
#include "rnd.h"
@@ -140,7 +140,6 @@ STATIC int rtk_init(struct ifnet *);
STATIC void rtk_stop(struct ifnet *, int);
STATIC void rtk_watchdog(struct ifnet *);
-STATIC void rtk_shutdown(void *);
STATIC int rtk_ifmedia_upd(struct ifnet *);
STATIC void rtk_ifmedia_sts(struct ifnet *, struct ifmediareq *);
@@ -157,7 +156,6 @@ STATIC void rtk_tick(void *);
STATIC int rtk_enable(struct rtk_softc *);
STATIC void rtk_disable(struct rtk_softc *);
-STATIC void rtk_power(int, void *);
STATIC void rtk_list_tx_init(struct rtk_softc *);
@@ -755,24 +753,6 @@ rtk_attach(struct rtk_softc *sc)
if_attach(ifp);
ether_ifattach(ifp, eaddr);
- /*
- * Make sure the interface is shutdown during reboot.
- */
- sc->sc_sdhook = shutdownhook_establish(rtk_shutdown, sc);
- if (sc->sc_sdhook == NULL)
- aprint_error_dev(self,
- "WARNING: unable to establish shutdown hook\n");
- /*
- * Add a suspend hook to make sure we come back up after a
- * resume.
- */
- sc->sc_powerhook = powerhook_establish(device_xname(self),
- rtk_power, sc);
- if (sc->sc_powerhook == NULL)
- aprint_error_dev(self,
- "WARNING: unable to establish power hook\n");
-
-
#if NRND > 0
rnd_attach_source(&sc->rnd_source, device_xname(self),
RND_TYPE_NET, 0);
@@ -886,9 +866,6 @@ rtk_detach(struct rtk_softc *sc)
RTK_RXBUFLEN + 16);
bus_dmamem_free(sc->sc_dmat, &sc->sc_dmaseg, sc->sc_dmanseg);
- shutdownhook_disestablish(sc->sc_sdhook);
- powerhook_disestablish(sc->sc_powerhook);
-
return 0;
}
@@ -926,40 +903,6 @@ rtk_disable(struct rtk_softc *sc)
}
/*
- * rtk_power:
- * Power management (suspend/resume) hook.
- */
-void
-rtk_power(int why, void *arg)
-{
- struct rtk_softc *sc = (void *)arg;
- struct ifnet *ifp = &sc->ethercom.ec_if;
- int s;
-
- s = splnet();
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- rtk_stop(ifp, 0);
- if (sc->sc_power != NULL)
- (*sc->sc_power)(sc, why);
- break;
- case PWR_RESUME:
- if (ifp->if_flags & IFF_UP) {
- if (sc->sc_power != NULL)
- (*sc->sc_power)(sc, why);
- rtk_init(ifp);
- }
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
- }
- splx(s);
-}
-
-/*
* A frame has been uploaded: pass the resulting mbuf chain up to
* the higher level protocols.
*
@@ -1619,18 +1562,6 @@ rtk_stop(struct ifnet *ifp, int disable)
ifp->if_timer = 0;
}
-/*
- * Stop all chip I/O so that the kernel's probe routines don't
- * get confused by errant DMAs when rebooting.
- */
-STATIC void
-rtk_shutdown(void *arg)
-{
- struct rtk_softc *sc = (struct rtk_softc *)arg;
-
- rtk_stop(&sc->ethercom.ec_if, 0);
-}
-
STATIC void
rtk_tick(void *arg)
{
diff --git a/sys/dev/ic/rtl81x9var.h b/sys/dev/ic/rtl81x9var.h
index e1bb8b955d3..c35edd47750 100644
--- a/sys/dev/ic/rtl81x9var.h
+++ b/sys/dev/ic/rtl81x9var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rtl81x9var.h,v 1.39 2007/03/21 12:17:31 tsutsui Exp $ */
+/* $NetBSD: rtl81x9var.h,v 1.40 2007/12/09 20:27:59 jmcneill Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -215,13 +215,9 @@ struct rtk_softc {
int sc_txthresh; /* Early tx threshold */
int sc_rev; /* MII revision */
- void *sc_sdhook; /* shutdown hook */
- void *sc_powerhook; /* power management hook */
-
/* Power management hooks. */
int (*sc_enable) (struct rtk_softc *);
void (*sc_disable) (struct rtk_softc *);
- void (*sc_power) (struct rtk_softc *, int);
#if NRND > 0
rndsource_element_t rnd_source;
#endif
diff --git a/sys/dev/ic/spic.c b/sys/dev/ic/spic.c
index f169291355c..a9732c0f33c 100644
--- a/sys/dev/ic/spic.c
+++ b/sys/dev/ic/spic.c
@@ -1,4 +1,4 @@
-/* $NetBSD: spic.c,v 1.9 2007/10/19 12:00:02 ad Exp $ */
+/* $NetBSD: spic.c,v 1.10 2007/12/09 20:28:00 jmcneill Exp $ */
/*
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -56,7 +56,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spic.c,v 1.9 2007/10/19 12:00:02 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spic.c,v 1.10 2007/12/09 20:28:00 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -74,6 +74,9 @@ __KERNEL_RCSID(0, "$NetBSD: spic.c,v 1.9 2007/10/19 12:00:02 ad Exp $");
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsmousevar.h>
+#define SPIC_EVENT_BRIGHTNESS_DOWN 0x15
+#define SPIC_EVENT_BRIGHTNESS_UP 0x16
+
#define POLLRATE (hz/30)
/* Some hardware constants */
@@ -205,6 +208,12 @@ spic_intr(void *v) {
case 0x1d:
dz -= 0x20;
break;
+ case SPIC_EVENT_BRIGHTNESS_UP:
+ pmf_event_inject(&sc->sc_dev, PMFE_DISPLAY_BRIGHTNESS_UP);
+ break;
+ case SPIC_EVENT_BRIGHTNESS_DOWN:
+ pmf_event_inject(&sc->sc_dev, PMFE_DISPLAY_BRIGHTNESS_DOWN);
+ break;
default:
printf("spic0: v1=0x%02x v2=0x%02x\n", v1, v2);
goto skip;
diff --git a/sys/dev/ic/vga.c b/sys/dev/ic/vga.c
index 2fe1cef7466..5a08014a6ef 100644
--- a/sys/dev/ic/vga.c
+++ b/sys/dev/ic/vga.c
@@ -1,4 +1,4 @@
-/* $NetBSD: vga.c,v 1.96 2007/10/19 12:00:04 ad Exp $ */
+/* $NetBSD: vga.c,v 1.97 2007/12/09 20:28:00 jmcneill Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vga.c,v 1.96 2007/10/19 12:00:04 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vga.c,v 1.97 2007/12/09 20:28:00 jmcneill Exp $");
/* for WSCONS_SUPPORT_PCVTFONTS */
#include "opt_wsdisplay_compat.h"
@@ -1488,3 +1488,11 @@ vga_setborder(struct vga_config *vc, u_int value)
return (0);
}
#endif /* WSDISPLAY_CUSTOM_BORDER */
+
+void
+vga_resume(struct vga_softc *sc)
+{
+#ifdef VGA_RESET_ON_RESUME
+ vga_initregs(&sc->sc_vc->hdl);
+#endif
+}
diff --git a/sys/dev/ic/vga_subr.c b/sys/dev/ic/vga_subr.c
index 45f4b4e5807..ca951eeb3a3 100644
--- a/sys/dev/ic/vga_subr.c
+++ b/sys/dev/ic/vga_subr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: vga_subr.c,v 1.22 2007/10/19 12:00:04 ad Exp $ */
+/* $NetBSD: vga_subr.c,v 1.23 2007/12/09 20:28:00 jmcneill Exp $ */
/*
* Copyright (c) 1998
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vga_subr.c,v 1.22 2007/10/19 12:00:04 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vga_subr.c,v 1.23 2007/12/09 20:28:00 jmcneill Exp $");
/* for WSDISPLAY_BORDER_COLOR */
#include "opt_wsdisplay_border.h"
@@ -48,9 +48,6 @@ __KERNEL_RCSID(0, "$NetBSD: vga_subr.c,v 1.22 2007/10/19 12:00:04 ad Exp $");
static void fontram(struct vga_handle *);
static void textram(struct vga_handle *);
-#ifdef VGA_RESET
-static void vga_initregs(struct vga_handle *);
-#endif
static void
fontram(struct vga_handle *vh)
@@ -214,7 +211,6 @@ vga_load_builtinfont(struct vga_handle *vh, u_int8_t *font, int firstchar,
}
#endif /* !VGA_RASTERCONSOLE */
-#ifdef VGA_RESET
/*
* vga_reset():
* Reset VGA registers to put it into 80x25 text mode. (mode 3)
@@ -375,7 +371,7 @@ static const u_int8_t vga_dacpal[] = {
0x3f, 0x3f, 0x3f /* WHITE */
};
-static void
+void
vga_initregs(vh)
struct vga_handle *vh;
{
@@ -427,4 +423,3 @@ vga_initregs(vh)
/* reenable video */
vga_ts_write(vh, mode, vga_ts[1] & ~VGA_TS_MODE_BLANK);
}
-#endif /* VGA_RESET */
diff --git a/sys/dev/ic/vgavar.h b/sys/dev/ic/vgavar.h
index 83552d6e7a8..20575f84f61 100644
--- a/sys/dev/ic/vgavar.h
+++ b/sys/dev/ic/vgavar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: vgavar.h,v 1.26 2007/03/04 06:02:03 christos Exp $ */
+/* $NetBSD: vgavar.h,v 1.27 2007/12/09 20:28:00 jmcneill Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -192,6 +192,8 @@ int vga_is_console(bus_space_tag_t, int);
int vga_cnattach(bus_space_tag_t, bus_space_tag_t, int, int);
int vga_cndetach(void);
+void vga_resume(struct vga_softc *);
+
#ifndef VGA_RASTERCONSOLE
struct wsscreen_descr;
void vga_loadchars(struct vga_handle *, int, int, int, int, const char *);
@@ -204,8 +206,7 @@ void vga_setscreentype(struct vga_handle *, const struct wsscreen_descr *);
#else /* !VGA_RASTERCONSOLE */
void vga_load_builtinfont(struct vga_handle *, u_int8_t *, int, int);
#endif /* !VGA_RASTERCONSOLE */
-#ifdef VGA_RESET
void vga_reset(struct vga_handle *, void (*)(struct vga_handle *));
-#endif
+void vga_initregs(struct vga_handle *);
extern int vga_no_builtinfont;
diff --git a/sys/dev/ic/wi.c b/sys/dev/ic/wi.c
index 23c90e2ab32..af4ca44a71a 100644
--- a/sys/dev/ic/wi.c
+++ b/sys/dev/ic/wi.c
@@ -1,4 +1,4 @@
-/* $NetBSD: wi.c,v 1.222 2007/10/19 12:00:05 ad Exp $ */
+/* $NetBSD: wi.c,v 1.223 2007/12/09 20:28:00 jmcneill Exp $ */
/*-
* Copyright (c) 2004 The NetBSD Foundation, Inc.
@@ -106,7 +106,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.222 2007/10/19 12:00:05 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.223 2007/12/09 20:28:00 jmcneill Exp $");
#define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */
#define WI_HERMES_STATS_WAR /* Work around stats counter bug. */
@@ -630,43 +630,8 @@ wi_activate(struct device *self, enum devact act)
splx(s);
return rv;
}
-
-void
-wi_power(struct wi_softc *sc, int why)
-{
- struct ifnet *ifp = &sc->sc_if;
- int s;
-
- s = splnet();
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- wi_stop(ifp, 1);
- break;
- case PWR_RESUME:
- if (ifp->if_flags & IFF_UP) {
- wi_init(ifp);
- (void)wi_intr(sc);
- }
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
- }
- splx(s);
-}
#endif /* __NetBSD__ */
-void
-wi_shutdown(struct wi_softc *sc)
-{
- struct ifnet *ifp = &sc->sc_if;
-
- if (sc->sc_attached)
- wi_stop(ifp, 1);
-}
-
int
wi_intr(void *arg)
{
diff --git a/sys/dev/ic/wivar.h b/sys/dev/ic/wivar.h
index d63ae1cdb39..e6e288be062 100644
--- a/sys/dev/ic/wivar.h
+++ b/sys/dev/ic/wivar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: wivar.h,v 1.59 2007/03/04 06:02:04 christos Exp $ */
+/* $NetBSD: wivar.h,v 1.60 2007/12/09 20:28:00 jmcneill Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -285,5 +285,3 @@ int wi_attach(struct wi_softc *, const u_int8_t *);
int wi_detach(struct wi_softc *);
int wi_activate(struct device *, enum devact);
int wi_intr(void *arg);
-void wi_power(struct wi_softc *, int);
-void wi_shutdown(struct wi_softc *);
diff --git a/sys/dev/ieee1394/firewire.c b/sys/dev/ieee1394/firewire.c
index fe7c10d1b44..bd7bb26375b 100644
--- a/sys/dev/ieee1394/firewire.c
+++ b/sys/dev/ieee1394/firewire.c
@@ -1,4 +1,4 @@
-/* $NetBSD: firewire.c,v 1.16 2007/11/05 19:08:56 kiyohara Exp $ */
+/* $NetBSD: firewire.c,v 1.17 2007/12/09 20:28:01 jmcneill Exp $ */
/*-
* Copyright (c) 2003 Hidetoshi Shimokawa
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
@@ -563,6 +563,11 @@ FW_ATTACH(firewire)
fw_busreset(fc, FWBUSNOTREADY);
fc->ibr(fc);
+#ifdef __NetBSD__
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+#endif
+
FW_ATTACH_RETURN(0);
}
diff --git a/sys/dev/ieee1394/fwohci.c b/sys/dev/ieee1394/fwohci.c
index 4fc0eb99351..8e8b8784e45 100644
--- a/sys/dev/ieee1394/fwohci.c
+++ b/sys/dev/ieee1394/fwohci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fwohci.c,v 1.112 2007/11/06 15:24:11 kiyohara Exp $ */
+/* $NetBSD: fwohci.c,v 1.113 2007/12/09 20:28:01 jmcneill Exp $ */
/*-
* Copyright (c) 2003 Hidetoshi Shimokawa
@@ -37,7 +37,7 @@
*
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fwohci.c,v 1.112 2007/11/06 15:24:11 kiyohara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fwohci.c,v 1.113 2007/12/09 20:28:01 jmcneill Exp $");
#define ATRQ_CH 0
#define ATRS_CH 1
@@ -2208,6 +2208,11 @@ fwohci_filt(void *arg)
{
struct fwohci_softc *sc = (struct fwohci_softc *)arg;
+#if defined(__NetBSD__)
+ if (!device_is_active(sc->fc.dev))
+ return (FILTER_STRAY);
+#endif
+
if (!(sc->intmask & OHCI_INT_EN)) {
/* polling mode */
return (FILTER_STRAY);
diff --git a/sys/dev/ieee1394/if_fwip.c b/sys/dev/ieee1394/if_fwip.c
index 20e2b177f26..be6a1f7a8d7 100644
--- a/sys/dev/ieee1394/if_fwip.c
+++ b/sys/dev/ieee1394/if_fwip.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_fwip.c,v 1.10 2007/11/05 19:08:57 kiyohara Exp $ */
+/* $NetBSD: if_fwip.c,v 1.11 2007/12/09 20:28:01 jmcneill Exp $ */
/*-
* Copyright (c) 2004
* Doug Rabson
@@ -313,6 +313,13 @@ FW_ATTACH(fwip)
FIREWIRE_IFATTACH(ifp, hwaddr);
splx(s);
+#if defined(__NetBSD__)
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, ifp);
+#endif
+
FWIPDEBUG(ifp, "interface created\n");
FW_ATTACH_RETURN(0);
}
diff --git a/sys/dev/isa/aps.c b/sys/dev/isa/aps.c
index 7d6227f1e2b..d3d6036704f 100644
--- a/sys/dev/isa/aps.c
+++ b/sys/dev/isa/aps.c
@@ -1,4 +1,4 @@
-/* $NetBSD: aps.c,v 1.4 2007/11/17 08:30:35 kefren Exp $ */
+/* $NetBSD: aps.c,v 1.5 2007/12/09 20:28:01 jmcneill Exp $ */
/* $OpenBSD: aps.c,v 1.15 2007/05/19 19:14:11 tedu Exp $ */
/*
@@ -23,7 +23,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: aps.c,v 1.4 2007/11/17 08:30:35 kefren Exp $");
+__KERNEL_RCSID(0, "$NetBSD: aps.c,v 1.5 2007/12/09 20:28:01 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -103,7 +103,6 @@ struct aps_softc {
struct callout sc_callout;
struct sensor_rec aps_data;
- void *sc_powerhook;
};
static int aps_match(struct device *, struct cfdata *, void *);
@@ -115,7 +114,8 @@ static uint8_t aps_mem_read_1(bus_space_tag_t, bus_space_handle_t,
int, uint8_t);
static void aps_refresh_sensor_data(struct aps_softc *sc);
static void aps_refresh(void *);
-static void aps_power(int, void *);
+static bool aps_suspend(device_t);
+static bool aps_resume(device_t);
CFATTACH_DECL(aps, sizeof(struct aps_softc),
aps_match, aps_attach, aps_detach, NULL);
@@ -251,12 +251,8 @@ aps_attach(struct device *parent, struct device *self, void *aux)
return;
}
- sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- aps_power,
- sc);
- if (sc->sc_powerhook == NULL)
- aprint_error("%s: can't establish powerhook\n",
- device_xname(&sc->sc_dev));
+ if (!pmf_device_register(self, aps_suspend, aps_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
/* Refresh sensor data every 0.5 seconds */
callout_init(&sc->sc_callout, 0);
@@ -404,28 +400,36 @@ aps_refresh(void *arg)
callout_schedule(&sc->sc_callout, (hz) / 2);
}
-static void
-aps_power(int why, void *arg)
+static bool
+aps_suspend(device_t dv)
{
- struct aps_softc *sc = (struct aps_softc *)arg;
+ struct aps_softc *sc = device_private(dv);
- if (why != PWR_RESUME) {
- callout_stop(&sc->sc_callout);
- } else {
- /*
- * Redo the init sequence on resume, because APS is
- * as forgetful as it is deaf.
- */
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, APS_INIT, 0x13);
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, APS_CMD, 0x01);
- bus_space_read_1(sc->sc_iot, sc->sc_ioh, APS_CMD);
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, APS_INIT, 0x13);
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, APS_CMD, 0x01);
-
- if (aps_mem_read_1(sc->sc_iot, sc->sc_ioh, APS_CMD, 0x00) &&
- aps_init(sc))
- callout_schedule(&sc->sc_callout, (hz) / 2);
- else
- printf("aps: failed to wake up\n");
- }
+ callout_stop(&sc->sc_callout);
+
+ return true;
+}
+
+static bool
+aps_resume(device_t dv)
+{
+ struct aps_softc *sc = device_private(dv);
+
+ /*
+ * Redo the init sequence on resume, because APS is
+ * as forgetful as it is deaf.
+ */
+ bus_space_write_1(sc->sc_iot, sc->sc_ioh, APS_INIT, 0x13);
+ bus_space_write_1(sc->sc_iot, sc->sc_ioh, APS_CMD, 0x01);
+ bus_space_read_1(sc->sc_iot, sc->sc_ioh, APS_CMD);
+ bus_space_write_1(sc->sc_iot, sc->sc_ioh, APS_INIT, 0x13);
+ bus_space_write_1(sc->sc_iot, sc->sc_ioh, APS_CMD, 0x01);
+
+ if (aps_mem_read_1(sc->sc_iot, sc->sc_ioh, APS_CMD, 0x00) &&
+ aps_init(sc))
+ callout_schedule(&sc->sc_callout, (hz) / 2);
+ else
+ aprint_error_dev(dv, "failed to wake up\n");
+
+ return true;
}
diff --git a/sys/dev/isa/isa.c b/sys/dev/isa/isa.c
index 08a81d0dcbc..dbe2640d4ce 100644
--- a/sys/dev/isa/isa.c
+++ b/sys/dev/isa/isa.c
@@ -1,4 +1,4 @@
-/* $NetBSD: isa.c,v 1.130 2007/12/01 04:50:23 jmcneill Exp $ */
+/* $NetBSD: isa.c,v 1.131 2007/12/09 20:28:01 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: isa.c,v 1.130 2007/12/01 04:50:23 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: isa.c,v 1.131 2007/12/09 20:28:01 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -136,6 +136,9 @@ isaattach(struct device *parent, struct device *self, void *aux)
/* Attach all indrect-config children. */
isarescan(self, "isa", wildcard);
+
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
int
diff --git a/sys/dev/isapnp/isapnp.c b/sys/dev/isapnp/isapnp.c
index 6e431927d1a..ffe98d8004a 100644
--- a/sys/dev/isapnp/isapnp.c
+++ b/sys/dev/isapnp/isapnp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: isapnp.c,v 1.54 2007/12/01 16:58:36 ad Exp $ */
+/* $NetBSD: isapnp.c,v 1.55 2007/12/09 20:28:02 jmcneill Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: isapnp.c,v 1.54 2007/12/01 16:58:36 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: isapnp.c,v 1.55 2007/12/09 20:28:02 jmcneill Exp $");
#include "isadma.h"
@@ -960,6 +960,9 @@ isapnp_attach(struct device *parent, struct device *self, void *aux)
#else
isapnp_callback(self);
#endif
+
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
/* isapnp_callback
diff --git a/sys/dev/mii/acphy.c b/sys/dev/mii/acphy.c
index 804fa205ae4..8e2f6997e14 100644
--- a/sys/dev/mii/acphy.c
+++ b/sys/dev/mii/acphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: acphy.c,v 1.19 2006/11/16 21:24:06 christos Exp $ */
+/* $NetBSD: acphy.c,v 1.20 2007/12/09 20:28:02 jmcneill Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acphy.c,v 1.19 2006/11/16 21:24:06 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acphy.c,v 1.20 2007/12/09 20:28:02 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -146,6 +146,9 @@ acphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/amhphy.c b/sys/dev/mii/amhphy.c
index 80403732903..0ad58bc13c2 100644
--- a/sys/dev/mii/amhphy.c
+++ b/sys/dev/mii/amhphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: amhphy.c,v 1.15 2006/11/16 21:24:06 christos Exp $ */
+/* $NetBSD: amhphy.c,v 1.16 2007/12/09 20:28:02 jmcneill Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: amhphy.c,v 1.15 2006/11/16 21:24:06 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amhphy.c,v 1.16 2007/12/09 20:28:02 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -120,6 +120,9 @@ amhphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/bmtphy.c b/sys/dev/mii/bmtphy.c
index 948a851bb80..b892f7dc3f9 100644
--- a/sys/dev/mii/bmtphy.c
+++ b/sys/dev/mii/bmtphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: bmtphy.c,v 1.22 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: bmtphy.c,v 1.23 2007/12/09 20:28:02 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -73,7 +73,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bmtphy.c,v 1.22 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bmtphy.c,v 1.23 2007/12/09 20:28:02 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -169,6 +169,9 @@ bmtphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/brgphy.c b/sys/dev/mii/brgphy.c
index 5eed9bd2a90..ee85941be5e 100644
--- a/sys/dev/mii/brgphy.c
+++ b/sys/dev/mii/brgphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: brgphy.c,v 1.34 2007/08/06 12:16:33 markd Exp $ */
+/* $NetBSD: brgphy.c,v 1.35 2007/12/09 20:28:02 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -74,7 +74,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: brgphy.c,v 1.34 2007/08/06 12:16:33 markd Exp $");
+__KERNEL_RCSID(0, "$NetBSD: brgphy.c,v 1.35 2007/12/09 20:28:02 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -300,6 +300,9 @@ brgphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/ciphy.c b/sys/dev/mii/ciphy.c
index 38e4a3610a5..4b09c5a32e4 100644
--- a/sys/dev/mii/ciphy.c
+++ b/sys/dev/mii/ciphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ciphy.c,v 1.12 2007/10/19 12:00:35 ad Exp $ */
+/* $NetBSD: ciphy.c,v 1.13 2007/12/09 20:28:02 jmcneill Exp $ */
/*-
* Copyright (c) 2004
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ciphy.c,v 1.12 2007/10/19 12:00:35 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ciphy.c,v 1.13 2007/12/09 20:28:02 jmcneill Exp $");
/*
* Driver for the Cicada CS8201 10/100/1000 copper PHY.
@@ -141,6 +141,9 @@ ciphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/dmphy.c b/sys/dev/mii/dmphy.c
index 81a7a0f7a0f..54533cfeaf4 100644
--- a/sys/dev/mii/dmphy.c
+++ b/sys/dev/mii/dmphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dmphy.c,v 1.27 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: dmphy.c,v 1.28 2007/12/09 20:28:02 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dmphy.c,v 1.27 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dmphy.c,v 1.28 2007/12/09 20:28:02 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -158,6 +158,9 @@ dmphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/exphy.c b/sys/dev/mii/exphy.c
index 851534c053b..f6c114fc28d 100644
--- a/sys/dev/mii/exphy.c
+++ b/sys/dev/mii/exphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: exphy.c,v 1.44 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: exphy.c,v 1.45 2007/12/09 20:28:02 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: exphy.c,v 1.44 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: exphy.c,v 1.45 2007/12/09 20:28:02 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -158,6 +158,9 @@ exphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/gentbi.c b/sys/dev/mii/gentbi.c
index ea6cbc30fc3..70f1afecaf1 100644
--- a/sys/dev/mii/gentbi.c
+++ b/sys/dev/mii/gentbi.c
@@ -1,4 +1,4 @@
-/* $NetBSD: gentbi.c,v 1.18 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: gentbi.c,v 1.19 2007/12/09 20:28:02 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -74,7 +74,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gentbi.c,v 1.18 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gentbi.c,v 1.19 2007/12/09 20:28:02 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -172,6 +172,9 @@ gentbiattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/glxtphy.c b/sys/dev/mii/glxtphy.c
index 572a32ae893..089f71443c9 100644
--- a/sys/dev/mii/glxtphy.c
+++ b/sys/dev/mii/glxtphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: glxtphy.c,v 1.17 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: glxtphy.c,v 1.18 2007/12/09 20:28:02 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: glxtphy.c,v 1.17 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: glxtphy.c,v 1.18 2007/12/09 20:28:02 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -158,6 +158,9 @@ glxtphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/gphyter.c b/sys/dev/mii/gphyter.c
index 79d038d085e..121702801d2 100644
--- a/sys/dev/mii/gphyter.c
+++ b/sys/dev/mii/gphyter.c
@@ -1,4 +1,4 @@
-/* $NetBSD: gphyter.c,v 1.19 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: gphyter.c,v 1.20 2007/12/09 20:28:03 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -75,7 +75,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gphyter.c,v 1.19 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gphyter.c,v 1.20 2007/12/09 20:28:03 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -183,6 +183,9 @@ gphyterattach(struct device *parent, struct device *self, void *aux)
if (strap & STRAP_NC_MODE)
aprint_normal(", pre-C5 BCM5400 compat enabled");
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/icsphy.c b/sys/dev/mii/icsphy.c
index 73598a58c9b..189790a5899 100644
--- a/sys/dev/mii/icsphy.c
+++ b/sys/dev/mii/icsphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: icsphy.c,v 1.41 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: icsphy.c,v 1.42 2007/12/09 20:28:03 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: icsphy.c,v 1.41 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: icsphy.c,v 1.42 2007/12/09 20:28:03 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -162,6 +162,9 @@ icsphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/igphy.c b/sys/dev/mii/igphy.c
index db95a44a086..83e223187c1 100644
--- a/sys/dev/mii/igphy.c
+++ b/sys/dev/mii/igphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: igphy.c,v 1.12 2007/08/28 01:11:50 msaitoh Exp $ */
+/* $NetBSD: igphy.c,v 1.13 2007/12/09 20:28:03 jmcneill Exp $ */
/*
* The Intel copyright applies to the analog register setup, and the
@@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: igphy.c,v 1.12 2007/08/28 01:11:50 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: igphy.c,v 1.13 2007/12/09 20:28:03 jmcneill Exp $");
#include "opt_mii.h"
@@ -174,6 +174,9 @@ igphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static void
diff --git a/sys/dev/mii/ikphy.c b/sys/dev/mii/ikphy.c
index 2185b9af9a9..3c9ab3ce748 100644
--- a/sys/dev/mii/ikphy.c
+++ b/sys/dev/mii/ikphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ikphy.c,v 1.3 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: ikphy.c,v 1.4 2007/12/09 20:28:03 jmcneill Exp $ */
/*******************************************************************************
Copyright (c) 2001-2005, Intel Corporation
@@ -64,7 +64,7 @@ POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ikphy.c,v 1.3 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ikphy.c,v 1.4 2007/12/09 20:28:03 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -148,6 +148,9 @@ ikphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/inphy.c b/sys/dev/mii/inphy.c
index 1d8e19fbafd..b6e1e0be5f6 100644
--- a/sys/dev/mii/inphy.c
+++ b/sys/dev/mii/inphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: inphy.c,v 1.43 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: inphy.c,v 1.44 2007/12/09 20:28:03 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: inphy.c,v 1.43 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: inphy.c,v 1.44 2007/12/09 20:28:03 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -164,6 +164,9 @@ inphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/iophy.c b/sys/dev/mii/iophy.c
index f819445aad0..d3848235796 100644
--- a/sys/dev/mii/iophy.c
+++ b/sys/dev/mii/iophy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: iophy.c,v 1.28 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: iophy.c,v 1.29 2007/12/09 20:28:03 jmcneill Exp $ */
/*
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: iophy.c,v 1.28 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: iophy.c,v 1.29 2007/12/09 20:28:03 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -153,6 +153,9 @@ iophyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/lxtphy.c b/sys/dev/mii/lxtphy.c
index 4d9fc9f3825..a4aa2a7d6dc 100644
--- a/sys/dev/mii/lxtphy.c
+++ b/sys/dev/mii/lxtphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: lxtphy.c,v 1.41 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: lxtphy.c,v 1.42 2007/12/09 20:28:03 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lxtphy.c,v 1.41 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lxtphy.c,v 1.42 2007/12/09 20:28:03 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -178,6 +178,9 @@ lxtphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/makphy.c b/sys/dev/mii/makphy.c
index e9d2be069a6..a92ba99a1fd 100644
--- a/sys/dev/mii/makphy.c
+++ b/sys/dev/mii/makphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: makphy.c,v 1.23 2007/02/23 03:03:10 msaitoh Exp $ */
+/* $NetBSD: makphy.c,v 1.24 2007/12/09 20:28:03 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: makphy.c,v 1.23 2007/02/23 03:03:10 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: makphy.c,v 1.24 2007/12/09 20:28:03 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -165,6 +165,9 @@ makphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static void
diff --git a/sys/dev/mii/mii_physubr.c b/sys/dev/mii/mii_physubr.c
index d891a148c4b..3fd1ed65249 100644
--- a/sys/dev/mii/mii_physubr.c
+++ b/sys/dev/mii/mii_physubr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: mii_physubr.c,v 1.53 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: mii_physubr.c,v 1.54 2007/12/09 20:28:03 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mii_physubr.c,v 1.53 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mii_physubr.c,v 1.54 2007/12/09 20:28:03 jmcneill Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -633,3 +633,12 @@ mii_phy_flowstatus(struct mii_softc *sc)
}
/* NOTREACHED */
}
+
+bool
+mii_phy_resume(device_t dv)
+{
+ struct mii_softc *sc = device_private(dv);
+
+ PHY_RESET(sc);
+ return true;
+}
diff --git a/sys/dev/mii/miivar.h b/sys/dev/mii/miivar.h
index e9c37b2fd94..17cac6a965d 100644
--- a/sys/dev/mii/miivar.h
+++ b/sys/dev/mii/miivar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: miivar.h,v 1.47 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: miivar.h,v 1.48 2007/12/09 20:28:03 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -233,6 +233,7 @@ void mii_attach(struct device *, struct mii_data *, int, int,
int, int);
void mii_activate(struct mii_data *, enum devact, int, int);
void mii_detach(struct mii_data *, int, int);
+bool mii_phy_resume(device_t);
int mii_mediachg(struct mii_data *);
void mii_tick(struct mii_data *);
diff --git a/sys/dev/mii/mvphy.c b/sys/dev/mii/mvphy.c
index f9ec87904bb..420fb5a3af3 100644
--- a/sys/dev/mii/mvphy.c
+++ b/sys/dev/mii/mvphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: mvphy.c,v 1.3 2007/02/17 23:23:38 jmcneill Exp $ */
+/* $NetBSD: mvphy.c,v 1.4 2007/12/09 20:28:03 jmcneill Exp $ */
/*-
* Copyright (c) 2006 Sam Leffler, Errno Consulting
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mvphy.c,v 1.3 2007/02/17 23:23:38 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvphy.c,v 1.4 2007/12/09 20:28:03 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -212,6 +212,9 @@ mvphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/nsphy.c b/sys/dev/mii/nsphy.c
index c51753b8bb4..0f6f38773a8 100644
--- a/sys/dev/mii/nsphy.c
+++ b/sys/dev/mii/nsphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: nsphy.c,v 1.49 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: nsphy.c,v 1.50 2007/12/09 20:28:04 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nsphy.c,v 1.49 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nsphy.c,v 1.50 2007/12/09 20:28:04 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -153,6 +153,9 @@ nsphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/nsphyter.c b/sys/dev/mii/nsphyter.c
index f647a689bee..274fcc5075a 100644
--- a/sys/dev/mii/nsphyter.c
+++ b/sys/dev/mii/nsphyter.c
@@ -1,4 +1,4 @@
-/* $NetBSD: nsphyter.c,v 1.26 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: nsphyter.c,v 1.27 2007/12/09 20:28:04 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -75,7 +75,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nsphyter.c,v 1.26 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nsphyter.c,v 1.27 2007/12/09 20:28:04 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -161,6 +161,9 @@ nsphyterattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/pnaphy.c b/sys/dev/mii/pnaphy.c
index 0d065408908..c23ba94abdc 100644
--- a/sys/dev/mii/pnaphy.c
+++ b/sys/dev/mii/pnaphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pnaphy.c,v 1.16 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: pnaphy.c,v 1.17 2007/12/09 20:28:04 jmcneill Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -47,7 +47,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pnaphy.c,v 1.16 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pnaphy.c,v 1.17 2007/12/09 20:28:04 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -130,6 +130,9 @@ pnaphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/qsphy.c b/sys/dev/mii/qsphy.c
index 8e6bf5a1334..529b31e4724 100644
--- a/sys/dev/mii/qsphy.c
+++ b/sys/dev/mii/qsphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: qsphy.c,v 1.40 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: qsphy.c,v 1.41 2007/12/09 20:28:04 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: qsphy.c,v 1.40 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: qsphy.c,v 1.41 2007/12/09 20:28:04 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -152,6 +152,9 @@ qsphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/rgephy.c b/sys/dev/mii/rgephy.c
index b66b119be99..56a28aca2b7 100644
--- a/sys/dev/mii/rgephy.c
+++ b/sys/dev/mii/rgephy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rgephy.c,v 1.16 2006/12/03 03:16:48 tsutsui Exp $ */
+/* $NetBSD: rgephy.c,v 1.17 2007/12/09 20:28:04 jmcneill Exp $ */
/*
* Copyright (c) 2003
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rgephy.c,v 1.16 2006/12/03 03:16:48 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rgephy.c,v 1.17 2007/12/09 20:28:04 jmcneill Exp $");
/*
@@ -153,6 +153,9 @@ rgephy_attach(struct device *parent, struct device *self, void *aux)
PHY_RESET(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/rlphy.c b/sys/dev/mii/rlphy.c
index 28359af8313..3daf968022f 100644
--- a/sys/dev/mii/rlphy.c
+++ b/sys/dev/mii/rlphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rlphy.c,v 1.18 2007/11/06 00:58:32 uwe Exp $ */
+/* $NetBSD: rlphy.c,v 1.19 2007/12/09 20:28:04 jmcneill Exp $ */
/* $OpenBSD: rlphy.c,v 1.20 2005/07/31 05:27:30 pvalchev Exp $ */
/*
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rlphy.c,v 1.18 2007/11/06 00:58:32 uwe Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rlphy.c,v 1.19 2007/12/09 20:28:04 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -140,6 +140,9 @@ rlphyattach(struct device *parent, struct device *self, void *aux)
if (sc->mii_capabilities & BMSR_MEDIAMASK)
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
int
diff --git a/sys/dev/mii/sqphy.c b/sys/dev/mii/sqphy.c
index 56c1fb175a0..1298f0b43ce 100644
--- a/sys/dev/mii/sqphy.c
+++ b/sys/dev/mii/sqphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sqphy.c,v 1.42 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: sqphy.c,v 1.43 2007/12/09 20:28:04 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sqphy.c,v 1.42 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sqphy.c,v 1.43 2007/12/09 20:28:04 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -173,6 +173,9 @@ sqphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/tlphy.c b/sys/dev/mii/tlphy.c
index de7229de166..ca2940d71ba 100644
--- a/sys/dev/mii/tlphy.c
+++ b/sys/dev/mii/tlphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tlphy.c,v 1.51 2007/10/19 12:00:36 ad Exp $ */
+/* $NetBSD: tlphy.c,v 1.52 2007/12/09 20:28:04 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tlphy.c,v 1.51 2007/10/19 12:00:36 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tlphy.c,v 1.52 2007/12/09 20:28:04 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -200,6 +200,9 @@ tlphyattach(struct device *parent, struct device *self, void *aux)
aprint_normal("\n");
#undef ADD
#undef PRINT
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/tqphy.c b/sys/dev/mii/tqphy.c
index 9f5e63d2748..442f9c2932a 100644
--- a/sys/dev/mii/tqphy.c
+++ b/sys/dev/mii/tqphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tqphy.c,v 1.31 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: tqphy.c,v 1.32 2007/12/09 20:28:04 jmcneill Exp $ */
/*
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -73,7 +73,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tqphy.c,v 1.31 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tqphy.c,v 1.32 2007/12/09 20:28:04 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -165,6 +165,9 @@ tqphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/ukphy.c b/sys/dev/mii/ukphy.c
index b868d5e89c8..5d8fe3e535b 100644
--- a/sys/dev/mii/ukphy.c
+++ b/sys/dev/mii/ukphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ukphy.c,v 1.30 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: ukphy.c,v 1.31 2007/12/09 20:28:04 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ukphy.c,v 1.30 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ukphy.c,v 1.31 2007/12/09 20:28:04 jmcneill Exp $");
#include "opt_mii.h"
@@ -175,6 +175,9 @@ ukphyattach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/mii/urlphy.c b/sys/dev/mii/urlphy.c
index 5b34f138e08..87e61fd138b 100644
--- a/sys/dev/mii/urlphy.c
+++ b/sys/dev/mii/urlphy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: urlphy.c,v 1.18 2006/11/16 21:24:07 christos Exp $ */
+/* $NetBSD: urlphy.c,v 1.19 2007/12/09 20:28:04 jmcneill Exp $ */
/*
* Copyright (c) 2001, 2002
* Shingo WATANABE <nabe@nabechan.org>. All rights reserved.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: urlphy.c,v 1.18 2006/11/16 21:24:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: urlphy.c,v 1.19 2007/12/09 20:28:04 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -131,6 +131,9 @@ urlphy_attach(struct device *parent, struct device *self, void *aux)
else
mii_phy_add_media(sc);
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, mii_phy_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/pad/pad.c b/sys/dev/pad/pad.c
index 8c6f91e678e..84564631508 100644
--- a/sys/dev/pad/pad.c
+++ b/sys/dev/pad/pad.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pad.c,v 1.3 2007/12/05 07:06:52 ad Exp $ */
+/* $NetBSD: pad.c,v 1.4 2007/12/09 20:28:04 jmcneill Exp $ */
/*-
* Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.3 2007/12/05 07:06:52 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.4 2007/12/09 20:28:04 jmcneill Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -254,7 +254,6 @@ pad_attach(struct device *parent, struct device *self, void *opaque)
sc = (pad_softc_t *)self;
- aprint_normal_dev(self, "Pseudo Audio Device\n");
aprint_normal_dev(self, "outputs: 44100Hz, 16-bit, stereo\n");
sc->sc_open = 0;
@@ -272,6 +271,9 @@ pad_attach(struct device *parent, struct device *self, void *opaque)
sc->sc_rpos = sc->sc_wpos = 0;
sc->sc_audiodev = (void *)audio_attach_mi(&pad_hw_if, sc, &sc->sc_dev);
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
return;
}
diff --git a/sys/dev/pci/agp.c b/sys/dev/pci/agp.c
index 8bcece80232..dadf6b5f536 100644
--- a/sys/dev/pci/agp.c
+++ b/sys/dev/pci/agp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: agp.c,v 1.53 2007/12/05 07:06:52 ad Exp $ */
+/* $NetBSD: agp.c,v 1.54 2007/12/09 20:28:05 jmcneill Exp $ */
/*-
* Copyright (c) 2000 Doug Rabson
@@ -65,7 +65,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: agp.c,v 1.53 2007/12/05 07:06:52 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: agp.c,v 1.54 2007/12/09 20:28:05 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -103,6 +103,7 @@ static int agp_deallocate_user(struct agp_softc *, int);
static int agp_bind_user(struct agp_softc *, agp_bind *);
static int agp_unbind_user(struct agp_softc *, agp_unbind *);
static int agpdev_match(struct pci_attach_args *);
+static bool agp_resume(device_t);
#include "agp_ali.h"
#include "agp_amd.h"
@@ -334,6 +335,11 @@ agpattach(struct device *parent, struct device *self, void *aux)
(unsigned long)AGP_GET_APERTURE(sc));
else
sc->as_chipc = NULL;
+
+ if (!device_pmf_is_registered(self)) {
+ if (!pmf_device_register(self, NULL, agp_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ }
}
CFATTACH_DECL(agp, sizeof(struct agp_softc),
@@ -1082,3 +1088,11 @@ agp_free_dmamem(bus_dma_tag_t tag, size_t size, bus_dmamap_t map,
bus_dmamem_unmap(tag, vaddr, size);
bus_dmamem_free(tag, seg, nseg);
}
+
+static bool
+agp_resume(device_t dv)
+{
+ agp_flush_cache();
+
+ return true;
+}
diff --git a/sys/dev/pci/agp_i810.c b/sys/dev/pci/agp_i810.c
index c3aff255fd3..0b141f8d186 100644
--- a/sys/dev/pci/agp_i810.c
+++ b/sys/dev/pci/agp_i810.c
@@ -1,4 +1,4 @@
-/* $NetBSD: agp_i810.c,v 1.46 2007/11/24 02:19:37 markd Exp $ */
+/* $NetBSD: agp_i810.c,v 1.47 2007/12/09 20:28:05 jmcneill Exp $ */
/*-
* Copyright (c) 2000 Doug Rabson
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.46 2007/11/24 02:19:37 markd Exp $");
+__KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.47 2007/12/09 20:28:05 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -95,8 +95,7 @@ struct agp_i810_softc {
bus_space_handle_t gtt_bsh; /* GTT bus_space handle */
struct pci_attach_args vga_pa;
- void *sc_powerhook;
- struct pci_conf_state sc_pciconf;
+ u_int32_t pgtblctl;
};
static u_int32_t agp_i810_get_aperture(struct agp_softc *);
@@ -110,7 +109,9 @@ static struct agp_memory *agp_i810_alloc_memory(struct agp_softc *, int,
static int agp_i810_free_memory(struct agp_softc *, struct agp_memory *);
static int agp_i810_bind_memory(struct agp_softc *, struct agp_memory *, off_t);
static int agp_i810_unbind_memory(struct agp_softc *, struct agp_memory *);
-static void agp_i810_powerhook(int, void *);
+
+static bool agp_i810_resume(device_t);
+static int agp_i810_init(struct agp_softc *);
static int agp_i810_init(struct agp_softc *);
@@ -331,6 +332,9 @@ agp_i810_attach(struct device *parent, struct device *self, void *aux)
gatt->ag_entries = AGP_GET_APERTURE(sc) >> AGP_PAGE_SHIFT;
+ if (!pmf_device_register(self, NULL, agp_i810_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
return agp_i810_init(sc);
}
@@ -500,12 +504,6 @@ static int agp_i810_init(struct agp_softc *sc)
*/
agp_flush_cache();
- isc->sc_powerhook = powerhook_establish(sc->as_dev.dv_xname,
- agp_i810_powerhook, sc);
- if (isc->sc_powerhook == NULL)
- printf("%s: WARNING: unable to establish PCI power hook\n",
- sc->as_dev.dv_xname);
-
#if 0
/*
* another device (drm) may need access to this region
@@ -888,17 +886,14 @@ agp_i810_unbind_memory(struct agp_softc *sc, struct agp_memory *mem)
return 0;
}
-static void
-agp_i810_powerhook(int why, void *arg)
+static bool
+agp_i810_resume(device_t dv)
{
- struct agp_softc *sc = (struct agp_softc *)arg;
+ struct agp_softc *sc = device_private(dv);
struct agp_i810_softc *isc = sc->as_chipc;
- if (why == PWR_RESUME) {
- pci_conf_restore(sc->as_pc, sc->as_tag, &isc->sc_pciconf);
- agp_flush_cache();
- } else if ((why == PWR_STANDBY) || (why == PWR_SUSPEND))
- pci_conf_capture(sc->as_pc, sc->as_tag, &isc->sc_pciconf);
+ isc->pgtblctl = READ4(AGP_I810_PGTBL_CTL);
+ agp_flush_cache();
- return;
+ return true;
}
diff --git a/sys/dev/pci/agp_intel.c b/sys/dev/pci/agp_intel.c
index c83fc2ddad4..46c56ccb104 100644
--- a/sys/dev/pci/agp_intel.c
+++ b/sys/dev/pci/agp_intel.c
@@ -1,4 +1,4 @@
-/* $NetBSD: agp_intel.c,v 1.24 2007/11/12 20:00:17 joerg Exp $ */
+/* $NetBSD: agp_intel.c,v 1.25 2007/12/09 20:28:05 jmcneill Exp $ */
/*-
* Copyright (c) 2000 Doug Rabson
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: agp_intel.c,v 1.24 2007/11/12 20:00:17 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: agp_intel.c,v 1.25 2007/12/09 20:28:05 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -64,8 +64,6 @@ struct agp_intel_softc {
#define CHIP_I850 0x4
#define CHIP_I865 0x5
- void *sc_powerhook;
- struct pci_conf_state sc_pciconf;
};
static u_int32_t agp_intel_get_aperture(struct agp_softc *);
@@ -73,8 +71,8 @@ static int agp_intel_set_aperture(struct agp_softc *, u_int32_t);
static int agp_intel_bind_page(struct agp_softc *, off_t, bus_addr_t);
static int agp_intel_unbind_page(struct agp_softc *, off_t);
static void agp_intel_flush_tlb(struct agp_softc *);
-static void agp_intel_powerhook(int, void *);
static int agp_intel_init(struct agp_softc *);
+static bool agp_intel_resume(device_t);
static struct agp_methods agp_intel_methods = {
agp_intel_get_aperture,
@@ -190,6 +188,9 @@ agp_intel_attach(struct device *parent, struct device *self, void *aux)
}
isc->gatt = gatt;
+ if (!pmf_device_register(self, NULL, agp_intel_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
return agp_intel_init(sc);
}
@@ -267,12 +268,6 @@ agp_intel_init(struct agp_softc *sc)
AGP_INTEL_ERRSTS, 0x70);
}
- isc->sc_powerhook = powerhook_establish(sc->as_dev.dv_xname,
- agp_intel_powerhook, sc);
- if (isc->sc_powerhook == NULL)
- aprint_error("%s: couldn't establish powerhook\n",
- sc->as_dev.dv_xname);
-
return (0);
}
@@ -284,9 +279,6 @@ agp_intel_detach(struct agp_softc *sc)
pcireg_t reg;
struct agp_intel_softc *isc = sc->as_chipc;
- if (isc->sc_powerhook)
- powerhook_disestablish(isc->sc_powerhook);
-
error = agp_generic_detach(sc);
if (error)
return error;
@@ -402,29 +394,13 @@ agp_intel_flush_tlb(struct agp_softc *sc)
}
}
-static void
-agp_intel_powerhook(int why, void *opaque)
+static bool
+agp_intel_resume(device_t dv)
{
- struct agp_softc *sc;
- struct agp_intel_softc *isc;
+ struct agp_softc *sc = device_private(dv);
- sc = (struct agp_softc *)opaque;
- isc = (struct agp_intel_softc *)sc->as_chipc;
-
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- pci_conf_capture(sc->as_pc, sc->as_tag, &isc->sc_pciconf);
- break;
- case PWR_RESUME:
- pci_conf_restore(sc->as_pc, sc->as_tag, &isc->sc_pciconf);
- agp_flush_cache();
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
- }
+ agp_intel_init(sc);
+ agp_flush_cache();
- return;
+ return true;
}
diff --git a/sys/dev/pci/ahcisata_pci.c b/sys/dev/pci/ahcisata_pci.c
index 30088a929ef..0f861877325 100644
--- a/sys/dev/pci/ahcisata_pci.c
+++ b/sys/dev/pci/ahcisata_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ahcisata_pci.c,v 1.1 2007/05/12 11:04:59 bouyer Exp $ */
+/* $NetBSD: ahcisata_pci.c,v 1.2 2007/12/09 20:28:05 jmcneill Exp $ */
/*
* Copyright (c) 2006 Manuel Bouyer.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_pci.c,v 1.1 2007/05/12 11:04:59 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_pci.c,v 1.2 2007/12/09 20:28:05 jmcneill Exp $");
#include <sys/types.h>
#include <sys/malloc.h>
@@ -39,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: ahcisata_pci.c,v 1.1 2007/05/12 11:04:59 bouyer Exp
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/disklabel.h>
+#include <sys/pmf.h>
#include <uvm/uvm_extern.h>
@@ -48,10 +49,19 @@ __KERNEL_RCSID(0, "$NetBSD: ahcisata_pci.c,v 1.1 2007/05/12 11:04:59 bouyer Exp
#include <dev/pci/pciidevar.h>
#include <dev/ic/ahcisatavar.h>
+struct ahci_pci_softc {
+ struct ahci_softc ah_sc; /* must come first, struct device */
+ pci_chipset_tag_t sc_pc;
+ pcitag_t sc_pcitag;
+};
+
+
static int ahci_pci_match(struct device *, struct cfdata *, void *);
static void ahci_pci_attach(struct device *, struct device *, void *);
+static bool ahci_pci_resume(device_t);
+
-CFATTACH_DECL(ahcisata_pci, sizeof(struct ahci_softc),
+CFATTACH_DECL(ahcisata_pci, sizeof(struct ahci_pci_softc),
ahci_pci_match, ahci_pci_attach, NULL, NULL);
static int
@@ -85,7 +95,8 @@ static void
ahci_pci_attach(struct device *parent, struct device *self, void *aux)
{
struct pci_attach_args *pa = aux;
- struct ahci_softc *sc = (struct ahci_softc *)self;
+ struct ahci_pci_softc *psc = (struct ahci_pci_softc *)self;
+ struct ahci_softc *sc = &psc->ah_sc;
bus_size_t size;
char devinfo[256];
const char *intrstr;
@@ -98,6 +109,9 @@ ahci_pci_attach(struct device *parent, struct device *self, void *aux)
aprint_error("%s: can't map ahci registers\n", AHCINAME(sc));
return;
}
+ psc->sc_pc = pa->pa_pc;
+ psc->sc_pcitag = pa->pa_tag;
+
pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
aprint_naive(": AHCI disk controller\n");
aprint_normal(": %s\n", devinfo);
@@ -116,4 +130,24 @@ ahci_pci_attach(struct device *parent, struct device *self, void *aux)
intrstr ? intrstr : "unknown interrupt");
sc->sc_dmat = pa->pa_dmat;
ahci_attach(sc);
+
+ if (!pmf_device_register(self, NULL, ahci_pci_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+}
+
+static bool
+ahci_pci_resume(device_t dv)
+{
+ struct ahci_pci_softc *psc = device_private(dv);
+ struct ahci_softc *sc = &psc->ah_sc;
+ int s;
+
+ s = splbio();
+ ahci_reset(sc);
+ ahci_setup_ports(sc);
+ ahci_reprobe_drives(sc);
+ ahci_enable_intrs(sc);
+ splx(s);
+
+ return true;
}
diff --git a/sys/dev/pci/auacer.c b/sys/dev/pci/auacer.c
index e49c72079b9..e9ebbdc5a87 100644
--- a/sys/dev/pci/auacer.c
+++ b/sys/dev/pci/auacer.c
@@ -1,4 +1,4 @@
-/* $NetBSD: auacer.c,v 1.17 2007/10/19 12:00:40 ad Exp $ */
+/* $NetBSD: auacer.c,v 1.18 2007/12/09 20:28:05 jmcneill Exp $ */
/*-
* Copyright (c) 2004 The NetBSD Foundation, Inc.
@@ -51,7 +51,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: auacer.c,v 1.17 2007/10/19 12:00:40 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: auacer.c,v 1.18 2007/12/09 20:28:05 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -133,10 +133,6 @@ struct auacer_softc {
int sc_dmamap_flags;
- /* Power Management */
- void *sc_powerhook;
- int sc_suspend;
-
#define AUACER_NFORMATS 3
struct audio_format sc_formats[AUACER_NFORMATS];
struct audio_encoding_set *sc_encodings;
@@ -194,7 +190,7 @@ static int auacer_allocmem(struct auacer_softc *, size_t, size_t,
struct auacer_dma *);
static int auacer_freemem(struct auacer_softc *, struct auacer_dma *);
-static void auacer_powerhook(int, void *);
+static bool auacer_resume(device_t);
static int auacer_set_rate(struct auacer_softc *, int, u_int);
static void auacer_reset(struct auacer_softc *sc);
@@ -350,14 +346,12 @@ auacer_attach(struct device *parent, struct device *self, void *aux)
return;
}
- /* Watch for power change */
- sc->sc_suspend = PWR_RESUME;
- sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- auacer_powerhook, sc);
-
audio_attach_mi(&auacer_hw_if, sc, &sc->sc_dev);
auacer_reset(sc);
+
+ if (!pmf_device_register(self, NULL, auacer_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
CFATTACH_DECL(auacer, sizeof(struct auacer_softc),
@@ -1030,38 +1024,14 @@ auacer_alloc_cdata(struct auacer_softc *sc)
return error;
}
-static void
-auacer_powerhook(int why, void *addr)
+static bool
+auacer_resume(device_t dv)
{
- struct auacer_softc *sc;
+ struct auacer_softc *sc = device_private(dv);
- sc = (struct auacer_softc *)addr;
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- /* Power down */
- DPRINTF(1, ("%s: power down\n", sc->sc_dev.dv_xname));
- sc->sc_suspend = why;
- break;
-
- case PWR_RESUME:
- /* Wake up */
- DPRINTF(1, ("%s: power resume\n", sc->sc_dev.dv_xname));
- if (sc->sc_suspend == PWR_RESUME) {
- printf("%s: resume without suspend.\n",
- sc->sc_dev.dv_xname);
- sc->sc_suspend = why;
- return;
- }
- sc->sc_suspend = why;
- auacer_reset_codec(sc);
- delay(1000);
- sc->codec_if->vtbl->restore_ports(sc->codec_if);
- break;
-
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
- }
+ auacer_reset_codec(sc);
+ delay(1000);
+ sc->codec_if->vtbl->restore_ports(sc->codec_if);
+
+ return true;
}
diff --git a/sys/dev/pci/auich.c b/sys/dev/pci/auich.c
index 924947dbdc0..624f379bd4d 100644
--- a/sys/dev/pci/auich.c
+++ b/sys/dev/pci/auich.c
@@ -1,4 +1,4 @@
-/* $NetBSD: auich.c,v 1.119 2007/10/19 12:00:40 ad Exp $ */
+/* $NetBSD: auich.c,v 1.120 2007/12/09 20:28:05 jmcneill 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.119 2007/10/19 12:00:40 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: auich.c,v 1.120 2007/12/09 20:28:05 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -217,12 +217,6 @@ struct auich_softc {
/* 440MX workaround */
int sc_dmamap_flags;
- /* Power Management */
- void *sc_powerhook;
- int sc_suspend;
- int sc_powerstate;
- struct pci_conf_state sc_pciconf;
-
/* sysctl */
struct sysctllog *sc_log;
uint32_t sc_ac97_clock;
@@ -291,7 +285,7 @@ static int auich_allocmem(struct auich_softc *, size_t, size_t,
struct auich_dma *);
static int auich_freemem(struct auich_softc *, struct auich_dma *);
-static void auich_powerhook(int, void *);
+static bool auich_resume(device_t);
static int auich_set_rate(struct auich_softc *, int, u_long);
static int auich_sysctl_verify(SYSCTLFN_ARGS);
static void auich_finish_attach(struct device *);
@@ -645,11 +639,9 @@ auich_attach(struct device *parent, struct device *self, void *aux)
return;
}
-
/* Watch for power change */
- sc->sc_suspend = PWR_RESUME;
- sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- auich_powerhook, sc);
+ if (!pmf_device_register(self, NULL, auich_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
config_interrupts(self, auich_finish_attach);
@@ -777,10 +769,6 @@ auich_finish_attach(struct device *self)
sc->sc_audiodev = audio_attach_mi(&auich_hw_if, sc, &sc->sc_dev);
-#if notyet
- auich_powerhook(PWR_SUSPEND, sc);
-#endif
-
return;
}
@@ -1245,6 +1233,10 @@ auich_intr(void *v)
#endif
sc = v;
+
+ if (!device_has_power(&sc->sc_dev))
+ return (0);
+
ret = 0;
#ifdef DIAGNOSTIC
csts = pci_conf_read(sc->sc_pc, sc->sc_pt, PCI_COMMAND_STATUS_REG);
@@ -1479,31 +1471,7 @@ auich_trigger_input(void *v, void *start, void *end, int blksize,
static int
auich_powerstate(void *v, int state)
{
-#if notyet
- struct auich_softc *sc;
- int rv;
-
- sc = (struct auich_softc *)v;
- rv = 0;
-
- switch (state) {
- case AUDIOPOWER_OFF:
- auich_powerhook(PWR_SUSPEND, sc);
- break;
- case AUDIOPOWER_ON:
- auich_powerhook(PWR_RESUME, sc);
- break;
- default:
- aprint_error("%s: unknown power state %d\n",
- sc->sc_dev.dv_xname, state);
- rv = 1;
- break;
- }
-
- return rv;
-#else
return 0;
-#endif
}
static int
@@ -1615,62 +1583,15 @@ auich_alloc_cdata(struct auich_softc *sc)
return error;
}
-static void
-auich_powerhook(int why, void *addr)
+static bool
+auich_resume(device_t dv)
{
- struct auich_softc *sc;
-
- sc = (struct auich_softc *)addr;
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- /* Power down */
- DPRINTF(1, ("%s: power down\n", sc->sc_dev.dv_xname));
-
- /* if we're already asleep, don't try to sleep again */
- if (sc->sc_suspend == PWR_SUSPEND ||
- sc->sc_suspend == PWR_STANDBY)
- break;
- sc->sc_suspend = why;
-
- DELAY(1000);
- pci_conf_capture(sc->sc_pc, sc->sc_pt, &sc->sc_pciconf);
-
- if (sc->sc_ih != NULL)
- pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
-
- break;
+ struct auich_softc *sc = device_private(dv);
- case PWR_RESUME:
- /* Wake up */
- DPRINTF(1, ("%s: power resume\n", sc->sc_dev.dv_xname));
- if (sc->sc_suspend == PWR_RESUME) {
- printf("%s: resume without suspend.\n",
- sc->sc_dev.dv_xname);
- sc->sc_suspend = why;
- return;
- }
-
- sc->sc_ih = pci_intr_establish(sc->sc_pc, sc->intrh, IPL_AUDIO,
- auich_intr, sc);
- if (sc->sc_ih == NULL) {
- aprint_error("%s: can't establish interrupt",
- sc->sc_dev.dv_xname);
- /* XXX jmcneill what should we do here? */
- return;
- }
- pci_conf_restore(sc->sc_pc, sc->sc_pt, &sc->sc_pciconf);
- sc->sc_suspend = why;
- auich_reset_codec(sc);
- DELAY(1000);
- (sc->codec_if->vtbl->restore_ports)(sc->codec_if);
- break;
-
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
- }
+ auich_reset_codec(sc);
+ DELAY(1000);
+ (sc->codec_if->vtbl->restore_ports)(sc->codec_if);
+ return true;
}
/*
diff --git a/sys/dev/pci/auixp.c b/sys/dev/pci/auixp.c
index 06702904ec0..f4aabc8ffa2 100644
--- a/sys/dev/pci/auixp.c
+++ b/sys/dev/pci/auixp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: auixp.c,v 1.24 2007/10/19 12:00:40 ad Exp $ */
+/* $NetBSD: auixp.c,v 1.25 2007/12/09 20:28:05 jmcneill 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.24 2007/10/19 12:00:40 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: auixp.c,v 1.25 2007/12/09 20:28:05 jmcneill Exp $");
#include <sys/types.h>
#include <sys/errno.h>
@@ -164,15 +164,6 @@ static int auixp_allocmem(struct auixp_softc *, size_t, size_t,
static int auixp_freemem(struct auixp_softc *, struct auixp_dma *);
static paddr_t auixp_mappage(void *, void *, off_t, int);
-
-/* power management (do we support that already?) */
-#if 0
-static void auixp_powerhook(int, void *);
-static int auixp_suspend(struct auixp_softc *);
-static int auixp_resume(struct auixp_softc *);
-#endif
-
-
/* Supporting subroutines */
static int auixp_init(struct auixp_softc *);
static void auixp_autodetect_codecs(struct auixp_softc *);
@@ -203,6 +194,8 @@ static void auixp_program_dma_chain(struct auixp_softc *,
static void auixp_dma_update(struct auixp_softc *, struct auixp_dma *);
static void auixp_update_busbusy(struct auixp_softc *);
+static bool auixp_resume(device_t);
+
#ifdef DEBUG_AUIXP
static struct auixp_softc *static_sc;
@@ -1107,7 +1100,7 @@ auixp_attach(struct device *parent, struct device *self, void *aux)
const char *intrstr;
uint32_t data;
char devinfo[256];
- int revision, len, error;
+ int revision, error;
sc = (struct auixp_softc *)self;
pa = (struct pci_attach_args *)aux;
@@ -1202,27 +1195,8 @@ auixp_attach(struct device *parent, struct device *self, void *aux)
return;
}
- /* XXX set up power hooks; not implemented yet XXX */
-
- len = 1; /* shut up gcc */
-#ifdef notyet
- /* create suspend save area */
- len = sizeof(uint16_t) * (ESA_REV_B_CODE_MEMORY_LENGTH
- + ESA_REV_B_DATA_MEMORY_LENGTH + 1);
- sc->savemem = (uint16_t *)malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO);
- if (sc->savemem == NULL) {
- aprint_error("%s: unable to allocate suspend buffer\n",
- sc->sc_dev.dv_xname);
- return;
- }
-
- sc->powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- auixp_powerhook, sc);
- if (sc->powerhook == NULL)
- aprint_error("%s: WARNING: unable to establish powerhook\n",
- sc->sc_dev.dv_xname);
-
-#endif
+ if (!pmf_device_register(self, NULL, auixp_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
/*
* delay further configuration of codecs and audio after interrupts
@@ -1393,8 +1367,7 @@ auixp_detach(struct device *self, int flags)
if (sc->sc_ios)
bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
- if (sc->savemem)
- free(sc->savemem, M_DEVBUF);
+ pmf_device_deregister(self);
return 0;
}
@@ -1785,52 +1758,17 @@ auixp_init(struct auixp_softc *sc)
return 0;
}
-
-/*
- * TODO power saving and suspend / resume support
- *
- */
-
-#if 0
-static void
-auixp_powerhook(int why, void *hdl)
-{
- struct auixp_softc *sc;
-
- sc = (struct auixp_softc *)hdl;
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- auixp_suspend(sc);
- break;
- case PWR_RESUME:
- auixp_resume(sc);
-#if notyet
- /* XXX fix me XXX */
- (sc->codec_if->vtbl->restore_ports)(sc->codec_if);
-#endif
- break;
- }
-}
-
-
-static int
-auixp_suspend(struct auixp_softc *sc)
+static bool
+auixp_resume(device_t dv)
{
+ struct auixp_softc *sc = device_private(dv);
- /* XXX no power functions yet XXX */
- return 0;
-}
-
+ auixp_reset_codec(sc);
+ delay(1000);
+ (sc->sc_codec[0].codec_if->vtbl->restore_ports)(sc->sc_codec[0].codec_if);
-static int
-auixp_resume(struct auixp_softc *sc)
-{
-
- /* XXX no power functions yet XXX */
- return 0;
+ return true;
}
-#endif /* 0 */
#ifdef DEBUG_AUIXP
diff --git a/sys/dev/pci/auixpvar.h b/sys/dev/pci/auixpvar.h
index 00c4843f0d4..8ab76770088 100644
--- a/sys/dev/pci/auixpvar.h
+++ b/sys/dev/pci/auixpvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: auixpvar.h,v 1.5 2007/03/04 06:02:16 christos Exp $*/
+/* $NetBSD: auixpvar.h,v 1.6 2007/12/09 20:28:06 jmcneill Exp $*/
/*
* Copyright (c) 2004, 2005 Reinoud Zandijk <reinoud@netbsd.org>
@@ -138,10 +138,6 @@ struct auixp_softc {
/* last set audio parameters */
struct audio_params sc_play_params;
struct audio_params sc_rec_params;
-
- /* suspend/resume */
- void *powerhook;
- uint16_t *savemem;
};
diff --git a/sys/dev/pci/autri.c b/sys/dev/pci/autri.c
index 75ba1cb1c22..c7a105e3a48 100644
--- a/sys/dev/pci/autri.c
+++ b/sys/dev/pci/autri.c
@@ -1,4 +1,4 @@
-/* $NetBSD: autri.c,v 1.35 2007/10/19 12:00:40 ad Exp $ */
+/* $NetBSD: autri.c,v 1.36 2007/12/09 20:28:06 jmcneill Exp $ */
/*
* Copyright (c) 2001 SOMEYA Yoshihiko and KUROSAWA Takahiro.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autri.c,v 1.35 2007/10/19 12:00:40 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autri.c,v 1.36 2007/12/09 20:28:06 jmcneill Exp $");
#include "midi.h"
@@ -97,7 +97,7 @@ static int autri_write_codec(void *, uint8_t, uint16_t);
static int autri_reset_codec(void *);
static enum ac97_host_flags autri_flags_codec(void *);
-static void autri_powerhook(int, void *);
+static bool autri_resume(device_t);
static int autri_init(void *);
static struct autri_dma *autri_find_dma(struct autri_softc *, void *);
static void autri_setup_channel(struct autri_softc *, int,
@@ -592,32 +592,28 @@ autri_attach(struct device *parent, struct device *self, void *aux)
return;
}
+ if (!pmf_device_register(self, NULL, autri_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
audio_attach_mi(&autri_hw_if, sc, &sc->sc_dev);
#if NMIDI > 0
midi_attach_mi(&autri_midi_hw_if, sc, &sc->sc_dev);
#endif
-
- sc->sc_old_power = PWR_RESUME;
- powerhook_establish(sc->sc_dev.dv_xname, autri_powerhook, sc);
}
CFATTACH_DECL(autri, sizeof(struct autri_softc),
autri_match, autri_attach, NULL, NULL);
-static void
-autri_powerhook(int why, void *addr)
+static bool
+autri_resume(device_t dv)
{
- struct autri_softc *sc;
+ struct autri_softc *sc = device_private(dv);
- sc = addr;
- if (why == PWR_RESUME && sc->sc_old_power == PWR_SUSPEND) {
- DPRINTF(("PWR_RESUME\n"));
- autri_init(sc);
- /*autri_reset_codec(&sc->sc_codec);*/
- (sc->sc_codec.codec_if->vtbl->restore_ports)(sc->sc_codec.codec_if);
- }
- sc->sc_old_power = why;
+ autri_init(sc);
+ (sc->sc_codec.codec_if->vtbl->restore_ports)(sc->sc_codec.codec_if);
+
+ return true;
}
static int
diff --git a/sys/dev/pci/autrivar.h b/sys/dev/pci/autrivar.h
index 87b2e5d90f4..3ea4da811c1 100644
--- a/sys/dev/pci/autrivar.h
+++ b/sys/dev/pci/autrivar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: autrivar.h,v 1.3 2007/03/04 06:02:16 christos Exp $ */
+/* $NetBSD: autrivar.h,v 1.4 2007/12/09 20:28:06 jmcneill Exp $ */
/*
* Copyright (c) 2001 SOMEYA Yoshihiko and KUROSAWA Takahiro.
@@ -86,8 +86,6 @@ struct autri_softc {
u_int32_t sc_class;
int sc_revision;
- int sc_old_power;
-
/*
* Play/record status
*/
diff --git a/sys/dev/pci/auvia.c b/sys/dev/pci/auvia.c
index bad34ff3308..8f7fd927f7e 100644
--- a/sys/dev/pci/auvia.c
+++ b/sys/dev/pci/auvia.c
@@ -1,4 +1,4 @@
-/* $NetBSD: auvia.c,v 1.60 2007/03/04 06:02:16 christos Exp $ */
+/* $NetBSD: auvia.c,v 1.61 2007/12/09 20:28:06 jmcneill Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -47,7 +47,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: auvia.c,v 1.60 2007/03/04 06:02:16 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: auvia.c,v 1.61 2007/12/09 20:28:06 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -118,7 +118,7 @@ static int auvia_trigger_output(void *, void *, void *, int,
static int auvia_trigger_input(void *, void *, void *, int,
void (*)(void *), void *,
const audio_params_t *);
-static void auvia_powerhook(int, void *);
+static bool auvia_resume(device_t);
static int auvia_intr(void *);
static int auvia_attach_codec(void *, struct ac97_codec_if *);
@@ -453,10 +453,8 @@ auvia_attach(struct device *parent, struct device *self, void *aux)
return;
}
- /* Watch for power change */
- sc->sc_suspend = PWR_RESUME;
- sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- auvia_powerhook, sc);
+ if (!pmf_device_register(self, NULL, auvia_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
audio_attach_mi(&auvia_hw_if, sc, &sc->sc_dev);
sc->codec_if->vtbl->unlock(sc->codec_if);
@@ -1113,36 +1111,14 @@ auvia_intr(void *arg)
return rval;
}
-static void
-auvia_powerhook(int why, void *addr)
+static bool
+auvia_resume(device_t dv)
{
- struct auvia_softc *sc;
-
- sc = addr;
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- /* Power down */
- sc->sc_suspend = why;
- break;
+ struct auvia_softc *sc = device_private(dv);
- case PWR_RESUME:
- /* Wake up */
- if (sc->sc_suspend == PWR_RESUME) {
- printf("%s: resume without suspend.\n",
- sc->sc_dev.dv_xname);
- sc->sc_suspend = why;
- return;
- }
- sc->sc_suspend = why;
- auvia_reset_codec(sc);
- DELAY(1000);
- (sc->codec_if->vtbl->restore_ports)(sc->codec_if);
- break;
+ auvia_reset_codec(sc);
+ DELAY(1000);
+ (sc->codec_if->vtbl->restore_ports)(sc->codec_if);
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
- }
+ return true;
}
diff --git a/sys/dev/pci/auviavar.h b/sys/dev/pci/auviavar.h
index 8df24181c84..cb583372d66 100644
--- a/sys/dev/pci/auviavar.h
+++ b/sys/dev/pci/auviavar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: auviavar.h,v 1.11 2007/02/21 23:00:00 thorpej Exp $ */
+/* $NetBSD: auviavar.h,v 1.12 2007/12/09 20:28:06 jmcneill Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -75,10 +75,6 @@ struct auvia_softc {
struct auvia_softc_chan sc_play, sc_record;
- /* Power Management */
- void *sc_powerhook;
- int sc_suspend;
-
#define AUVIA_NFORMATS 8
struct audio_format sc_formats[AUVIA_NFORMATS];
struct audio_encoding_set *sc_encodings;
diff --git a/sys/dev/pci/azalia.c b/sys/dev/pci/azalia.c
index a4a4ecabe91..44d17a12d94 100644
--- a/sys/dev/pci/azalia.c
+++ b/sys/dev/pci/azalia.c
@@ -1,4 +1,4 @@
-/* $NetBSD: azalia.c,v 1.51 2007/08/14 13:57:56 kent Exp $ */
+/* $NetBSD: azalia.c,v 1.52 2007/12/09 20:28:06 jmcneill Exp $ */
/*-
* Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: azalia.c,v 1.51 2007/08/14 13:57:56 kent Exp $");
+__KERNEL_RCSID(0, "$NetBSD: azalia.c,v 1.52 2007/12/09 20:28:06 jmcneill Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -115,6 +115,7 @@ typedef struct azalia_t {
struct device *audiodev;
pci_chipset_tag_t pc;
+ pcitag_t tag;
void *ih;
bus_space_tag_t iot;
bus_space_handle_t ioh;
@@ -142,6 +143,7 @@ typedef struct azalia_t {
int nistreams, nostreams, nbstreams;
stream_t pstream;
stream_t rstream;
+
int mode_cap;
} azalia_t;
#define XNAME(sc) ((sc)->dev.dv_xname)
@@ -158,12 +160,13 @@ static int azalia_pci_match(struct device *, struct cfdata *, void *);
static void azalia_pci_attach(struct device *, struct device *, void *);
static int azalia_pci_activate(struct device *, enum devact);
static int azalia_pci_detach(struct device *, int);
+static bool azalia_pci_resume(device_t);
static int azalia_intr(void *);
static int azalia_attach(azalia_t *);
static void azalia_attach_intr(struct device *);
-static int azalia_init_corb(azalia_t *);
+static int azalia_init_corb(azalia_t *, int);
static int azalia_delete_corb(azalia_t *);
-static int azalia_init_rirb(azalia_t *);
+static int azalia_init_rirb(azalia_t *, int);
static int azalia_delete_rirb(azalia_t *);
static int azalia_set_command(const azalia_t *, nid_t, int, uint32_t,
uint32_t);
@@ -173,7 +176,7 @@ static void azalia_rirb_intr(azalia_t *);
static int azalia_alloc_dmamem(azalia_t *, size_t, size_t, azalia_dma_t *);
static int azalia_free_dmamem(const azalia_t *, azalia_dma_t*);
-static int azalia_codec_init(codec_t *);
+static int azalia_codec_init(codec_t *, int);
static int azalia_codec_delete(codec_t *);
static void azalia_codec_add_bits(codec_t *, int, uint32_t, int);
static void azalia_codec_add_format(codec_t *, int, int, int, uint32_t,
@@ -185,7 +188,9 @@ static int azalia_codec_disconnect_stream(codec_t *, int);
static int azalia_widget_init(widget_t *, const codec_t *, int, const char *);
static int azalia_widget_init_audio(widget_t *, const codec_t *, const char *);
+#ifdef AZALIA_DEBUG
static int azalia_widget_print_audio(const widget_t *, const char *, int);
+#endif
static int azalia_widget_init_pin(widget_t *, const codec_t *);
static int azalia_widget_print_pin(const widget_t *, const char *);
static int azalia_widget_init_connection(widget_t *, const codec_t *, const char *);
@@ -327,6 +332,7 @@ azalia_pci_attach(struct device *parent, struct device *self,
return;
}
sc->pc = pa->pa_pc;
+ sc->tag = pa->pa_tag;
intrrupt_str = pci_intr_string(pa->pa_pc, ih);
sc->ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, azalia_intr, sc);
if (sc->ih == NULL) {
@@ -338,6 +344,9 @@ azalia_pci_attach(struct device *parent, struct device *self,
}
aprint_normal("%s: interrupting at %s\n", XNAME(sc), intrrupt_str);
+ if (!pmf_device_register(self, NULL, azalia_pci_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
sc->pciid = pa->pa_id;
vendor = pci_findvendor(pa->pa_id);
name = pci_findproduct(pa->pa_id);
@@ -418,6 +427,21 @@ azalia_pci_detach(struct device *self, int flags)
return 0;
}
+static bool
+azalia_pci_resume(device_t dv)
+{
+ azalia_t *az = device_private(dv);
+ int s;
+
+ s = splaudio();
+ azalia_attach(az);
+ splx(s);
+
+ azalia_attach_intr(&az->dev);
+
+ return true;
+}
+
static int
azalia_intr(void *v)
{
@@ -429,6 +453,9 @@ azalia_intr(void *v)
az = v;
ret = 0;
+ if (!device_has_power(&az->dev))
+ return 0;
+
intsts = AZ_READ_4(az, INTSTS);
if (intsts == 0)
return ret;
@@ -463,8 +490,10 @@ azalia_attach(azalia_t *az)
uint16_t gcap;
uint16_t statests;
- aprint_normal("%s: host: High Definition Audio rev. %d.%d\n",
- XNAME(az), AZ_READ_1(az, VMAJ), AZ_READ_1(az, VMIN));
+ if (az->audiodev == NULL)
+ aprint_normal("%s: host: High Definition Audio rev. %d.%d\n",
+ XNAME(az), AZ_READ_1(az, VMAJ), AZ_READ_1(az, VMIN));
+
gcap = AZ_READ_2(az, GCAP);
az->nistreams = HDA_GCAP_ISS(gcap);
az->nostreams = HDA_GCAP_OSS(gcap);
@@ -531,9 +560,10 @@ static void
azalia_attach_intr(struct device *self)
{
azalia_t *az;
- int err, i, c;
+ int err, i, c, reinit;
az = (azalia_t*)self;
+ reinit = az->audiodev == NULL ? 0 : 1;
AZ_WRITE_2(az, STATESTS, HDA_STATESTS_SDIWAKE);
AZ_WRITE_1(az, RIRBSTS, HDA_RIRBSTS_RINTFL | HDA_RIRBSTS_RIRBOIS);
@@ -542,10 +572,10 @@ azalia_attach_intr(struct device *self)
AZ_WRITE_4(az, DPUBASE, 0);
/* 4.4.1 Command Outbound Ring Buffer */
- if (azalia_init_corb(az))
+ if (azalia_init_corb(az, reinit))
goto err_exit;
/* 4.4.2 Response Inbound Ring Buffer */
- if (azalia_init_rirb(az))
+ if (azalia_init_rirb(az, reinit))
goto err_exit;
AZ_WRITE_4(az, INTCTL,
@@ -553,7 +583,7 @@ azalia_attach_intr(struct device *self)
c = -1;
for (i = 0; i < az->ncodecs; i++) {
- err = azalia_codec_init(&az->codecs[i]);
+ err = azalia_codec_init(&az->codecs[i], reinit);
if (!err && c < 0)
c = i;
}
@@ -568,15 +598,15 @@ azalia_attach_intr(struct device *self)
az->mode_cap &= ~AUMODE_RECORD;
/* Use stream#1 and #2. Don't use stream#0. */
- if (az->nostreams > 0 &&
- azalia_stream_init(&az->pstream, az, az->nistreams + 0,
- 1, AUMODE_PLAY))
- goto err_exit;
- if (az->nistreams > 0 &&
- azalia_stream_init(&az->rstream, az, 0, 2, AUMODE_RECORD))
- goto err_exit;
+ if (reinit == 0) {
+ if (azalia_stream_init(&az->pstream, az, az->nistreams + 0,
+ 1, AUMODE_PLAY))
+ goto err_exit;
+ if (azalia_stream_init(&az->rstream, az, 0, 2, AUMODE_RECORD))
+ goto err_exit;
- az->audiodev = audio_attach_mi(&azalia_hw_if, az, &az->dev);
+ az->audiodev = audio_attach_mi(&azalia_hw_if, az, &az->dev);
+ }
return;
err_exit:
azalia_pci_detach(self, 0);
@@ -584,7 +614,7 @@ err_exit:
}
static int
-azalia_init_corb(azalia_t *az)
+azalia_init_corb(azalia_t *az, int reinit)
{
int entries, err, i;
uint16_t corbrp, corbwp;
@@ -624,11 +654,14 @@ azalia_init_corb(azalia_t *az)
return -1;
}
- err = azalia_alloc_dmamem(az, entries * sizeof(corb_entry_t),
- 128, &az->corb_dma);
- if (err) {
- aprint_error("%s: can't allocate CORB buffer\n", XNAME(az));
- return err;
+ if (reinit == 0) {
+ err = azalia_alloc_dmamem(az, entries * sizeof(corb_entry_t),
+ 128, &az->corb_dma);
+ if (err) {
+ aprint_error("%s: can't allocate CORB buffer\n",
+ XNAME(az));
+ return err;
+ }
}
AZ_WRITE_4(az, CORBLBASE, (uint32_t)AZALIA_DMA_DMAADDR(&az->corb_dma));
AZ_WRITE_4(az, CORBUBASE, PTR_UPPER32(AZALIA_DMA_DMAADDR(&az->corb_dma)));
@@ -686,7 +719,7 @@ azalia_delete_corb(azalia_t *az)
}
static int
-azalia_init_rirb(azalia_t *az)
+azalia_init_rirb(azalia_t *az, int reinit)
{
int entries, err, i;
uint16_t rirbwp;
@@ -726,11 +759,14 @@ azalia_init_rirb(azalia_t *az)
return -1;
}
- err = azalia_alloc_dmamem(az, entries * sizeof(rirb_entry_t),
- 128, &az->rirb_dma);
- if (err) {
- aprint_error("%s: can't allocate RIRB buffer\n", XNAME(az));
- return err;
+ if (reinit == 0) {
+ err = azalia_alloc_dmamem(az, entries * sizeof(rirb_entry_t),
+ 128, &az->rirb_dma);
+ if (err) {
+ aprint_error("%s: can't allocate RIRB buffer\n",
+ XNAME(az));
+ return err;
+ }
}
AZ_WRITE_4(az, RIRBLBASE, (uint32_t)AZALIA_DMA_DMAADDR(&az->rirb_dma));
AZ_WRITE_4(az, RIRBUBASE, PTR_UPPER32(AZALIA_DMA_DMAADDR(&az->rirb_dma)));
@@ -743,8 +779,12 @@ azalia_init_rirb(azalia_t *az)
az->unsolq_rp = 0;
az->unsolq_wp = 0;
az->unsolq_kick = FALSE;
- az->unsolq = malloc(sizeof(rirb_entry_t) * UNSOLQ_SIZE,
- M_DEVBUF, M_ZERO | M_NOWAIT);
+ if (reinit == 0) {
+ az->unsolq = malloc(sizeof(rirb_entry_t) * UNSOLQ_SIZE,
+ M_DEVBUF, M_ZERO | M_NOWAIT);
+ } else {
+ memset(az->unsolq, 0, sizeof(rirb_entry_t) * UNSOLQ_SIZE);
+ }
if (az->unsolq == NULL) {
aprint_error("%s: can't allocate unsolicited response queue.\n",
XNAME(az));
@@ -984,7 +1024,7 @@ azalia_free_dmamem(const azalia_t *az, azalia_dma_t* d)
* ================================================================ */
static int
-azalia_codec_init(codec_t *this)
+azalia_codec_init(codec_t *this, int reinit)
{
#define LEAD_LEN 100
char lead[LEAD_LEN];
@@ -1006,21 +1046,26 @@ azalia_codec_init(codec_t *this)
return err;
this->vid = id;
this->subid = this->az->subid;
- err = azalia_codec_init_vtbl(this);
- if (err)
- return err;
- aprint_normal("%s: codec[%d]: ", XNAME(this->az), addr);
- if (this->name == NULL) {
- aprint_normal("0x%4.4x/0x%4.4x (rev. %u.%u)\n",
- id >> 16, id & 0xffff,
- COP_RID_REVISION(rev), COP_RID_STEPPING(rev));
- } else {
- aprint_normal("%s (rev. %u.%u)\n", this->name,
- COP_RID_REVISION(rev), COP_RID_STEPPING(rev));
+ if (!reinit) {
+ err = azalia_codec_init_vtbl(this);
+ if (err)
+ return err;
+ }
+
+ if (!reinit) {
+ aprint_normal("%s: codec[%d]: ", XNAME(this->az), addr);
+ if (this->name == NULL) {
+ aprint_normal("0x%4.4x/0x%4.4x (rev. %u.%u)\n",
+ id >> 16, id & 0xffff,
+ COP_RID_REVISION(rev), COP_RID_STEPPING(rev));
+ } else {
+ aprint_normal("%s (rev. %u.%u)\n", this->name,
+ COP_RID_REVISION(rev), COP_RID_STEPPING(rev));
+ }
+ aprint_normal("%s: codec[%d]: High Definition Audio rev. %u.%u\n",
+ XNAME(this->az), addr, COP_RID_MAJ(rev), COP_RID_MIN(rev));
}
- aprint_normal("%s: codec[%d]: High Definition Audio rev. %u.%u\n",
- XNAME(this->az), addr, COP_RID_MAJ(rev), COP_RID_MIN(rev));
/* identify function nodes */
err = this->comresp(this, CORB_NID_ROOT, CORB_GET_PARAMETER,
@@ -1046,12 +1091,12 @@ azalia_codec_init(codec_t *this)
if (COP_FTYPE(result) == COP_FTYPE_AUDIO) {
this->audiofunc = n + i;
break; /* XXX multiple audio functions? */
- } else if (COP_FTYPE(result) == COP_FTYPE_MODEM) {
+ } else if (COP_FTYPE(result) == COP_FTYPE_MODEM && !reinit) {
aprint_normal("%s: codec[%d]: No support for modem function groups\n",
XNAME(this->az), addr);
}
}
- if (this->audiofunc < 0) {
+ if (this->audiofunc < 0 && !reinit) {
aprint_error("%s: codec[%d] has no audio function groups\n",
XNAME(this->az), addr);
return -1;
@@ -1070,16 +1115,21 @@ azalia_codec_init(codec_t *this)
__func__, COP_NSUBNODES(result)));
this->wstart = COP_START_NID(result);
if (this->wstart < 2) {
- aprint_error("%s: invalid node structure\n", XNAME(this->az));
+ if (!reinit)
+ aprint_error("%s: invalid node structure\n",
+ XNAME(this->az));
return -1;
}
this->wend = this->wstart + COP_NSUBNODES(result);
- this->w = malloc(sizeof(widget_t) * this->wend, M_DEVBUF,
- M_ZERO | M_NOWAIT);
- if (this->w == NULL) {
- aprint_error("%s: out of memory\n", XNAME(this->az));
- return ENOMEM;
- }
+ if (!reinit) {
+ this->w = malloc(sizeof(widget_t) * this->wend, M_DEVBUF,
+ M_ZERO | M_NOWAIT);
+ if (this->w == NULL) {
+ aprint_error("%s: out of memory\n", XNAME(this->az));
+ return ENOMEM;
+ }
+ } else
+ memset(this->w, 0, sizeof(widget_t) * this->wend);
/* query the base parameters */
this->comresp(this, this->audiofunc, CORB_GET_PARAMETER,
@@ -1245,7 +1295,9 @@ azalia_codec_delete(codec_t *this)
int
azalia_codec_construct_format(codec_t *this, int newdac, int newadc)
{
+#ifdef AZALIA_DEBUG
char flagbuf[FLAGBUFLEN];
+#endif
const convgroup_t *group;
uint32_t bits_rates;
int prev_dac, prev_adc;
@@ -1329,6 +1381,7 @@ azalia_codec_construct_format(codec_t *this, int newdac, int newadc)
azalia_codec_add_bits(this, chan,
bits_rates, AUMODE_PLAY);
}
+#ifdef AZALIA_DEBUG
/* print playback capability */
if (prev_dac != this->dacs.cur) {
snprintf(flagbuf, FLAGBUFLEN, "%s: playback: ",
@@ -1336,6 +1389,7 @@ azalia_codec_construct_format(codec_t *this, int newdac, int newadc)
azalia_widget_print_audio(&this->w[group->conv[0]],
flagbuf, chan);
}
+#endif
}
/* register formats for recording */
@@ -1352,6 +1406,7 @@ azalia_codec_construct_format(codec_t *this, int newdac, int newadc)
azalia_codec_add_bits(this, chan,
bits_rates, AUMODE_RECORD);
}
+#ifdef AZALIA_DEBUG
/* print recording capability */
if (prev_adc != this->adcs.cur) {
snprintf(flagbuf, FLAGBUFLEN, "%s: recording: ",
@@ -1359,6 +1414,7 @@ azalia_codec_construct_format(codec_t *this, int newdac, int newadc)
azalia_widget_print_audio(&this->w[group->conv[0]],
flagbuf, chan);
}
+#endif
}
#ifdef DIAGNOSTIC
@@ -1706,6 +1762,7 @@ azalia_widget_init_audio(widget_t *this, const codec_t *codec, const char *lead)
return 0;
}
+#ifdef AZALIA_DEBUG
static int
azalia_widget_print_audio(const widget_t *this, const char *lead, int channels)
{
@@ -1730,6 +1787,7 @@ azalia_widget_print_audio(const widget_t *this, const char *lead, int channels)
aprint_normal("%sPCM formats=%s\n", lead, flagbuf);
return 0;
}
+#endif
static int
azalia_widget_init_pin(widget_t *this, const codec_t *codec)
diff --git a/sys/dev/pci/azalia_codec.c b/sys/dev/pci/azalia_codec.c
index c04fabb2fb2..4a7a69661fa 100644
--- a/sys/dev/pci/azalia_codec.c
+++ b/sys/dev/pci/azalia_codec.c
@@ -1,4 +1,4 @@
-/* $NetBSD: azalia_codec.c,v 1.49 2007/11/26 15:47:36 christos Exp $ */
+/* $NetBSD: azalia_codec.c,v 1.50 2007/12/09 20:28:06 jmcneill Exp $ */
/*-
* Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: azalia_codec.c,v 1.49 2007/11/26 15:47:36 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: azalia_codec.c,v 1.50 2007/12/09 20:28:06 jmcneill Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -111,6 +111,7 @@ static int alc260_mixer_init(codec_t *);
static int alc260_set_port(codec_t *, mixer_ctrl_t *);
static int alc260_get_port(codec_t *, mixer_ctrl_t *);
static int alc260_unsol_event(codec_t *, int);
+static int alc262_init_widget(const codec_t *, widget_t *, nid_t);
static int alc861_init_dacgroup(codec_t *);
static int alc861vdgr_init_dacgroup(codec_t *);
static int alc880_init_dacgroup(codec_t *);
@@ -167,6 +168,7 @@ azalia_codec_init_vtbl(codec_t *this)
break;
case 0x10ec0262:
this->name = "Realtek ALC262";
+ this->init_widget = alc262_init_widget;
break;
case 0x10ec0268:
this->name = "Realtek ALC268";
@@ -1998,6 +2000,22 @@ alc260_unsol_event(codec_t *this, int tag)
* ---------------------------------------------------------------- */
static int
+alc262_init_widget(const codec_t *this, widget_t *w, nid_t nid)
+{
+ switch (nid) {
+ case 0x0c:
+ strlcpy(w->name, AudioNmaster, sizeof(w->name));
+ break;
+ }
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------
+ * Realtek ALC861
+ * ---------------------------------------------------------------- */
+
+static int
alc861_init_dacgroup(codec_t *this)
{
static const convgroupset_t dacs = {
diff --git a/sys/dev/pci/cs4280.c b/sys/dev/pci/cs4280.c
index 96df6aa8b39..26eb558f9cb 100644
--- a/sys/dev/pci/cs4280.c
+++ b/sys/dev/pci/cs4280.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cs4280.c,v 1.47 2007/10/19 12:00:41 ad Exp $ */
+/* $NetBSD: cs4280.c,v 1.48 2007/12/09 20:28:07 jmcneill 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.47 2007/10/19 12:00:41 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cs4280.c,v 1.48 2007/12/09 20:28:07 jmcneill Exp $");
#include "midi.h"
@@ -110,8 +110,8 @@ static int cs4280_reset_codec(void *);
#endif
static enum ac97_host_flags cs4280_flags_codec(void *);
-/* For PowerHook */
-static void cs4280_power(int, void *);
+static bool cs4280_resume(device_t);
+static bool cs4280_suspend(device_t);
/* Internal functions */
static const struct cs4280_card_t * cs4280_identify_card(struct pci_attach_args *);
@@ -365,9 +365,8 @@ cs4280_attach(struct device *parent, struct device *self, void *aux)
midi_attach_mi(&cs4280_midi_hw_if, sc, &sc->sc_dev);
#endif
- sc->sc_suspend = PWR_RESUME;
- sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- cs4280_power, sc);
+ if (!pmf_device_register(self, cs4280_suspend, cs4280_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
/* Interrupt handling function */
@@ -912,99 +911,79 @@ cs4280_trigger_input(void *addr, void *start, void *end, int blksize,
return 0;
}
-/* Power Hook */
-static void
-cs4280_power(int why, void *v)
+static bool
+cs4280_suspend(device_t dv)
{
- static uint32_t pctl = 0, pba = 0, pfie = 0, pdtc = 0;
- static uint32_t cctl = 0, cba = 0, cie = 0;
- struct cs428x_softc *sc;
-
- sc = (struct cs428x_softc *)v;
- DPRINTF(("%s: cs4280_power why=%d\n", sc->sc_dev.dv_xname, why));
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- sc->sc_suspend = why;
-
- /* save current playback status */
- if (sc->sc_prun) {
- pctl = BA1READ4(sc, CS4280_PCTL);
- pfie = BA1READ4(sc, CS4280_PFIE);
- pba = BA1READ4(sc, CS4280_PBA);
- pdtc = BA1READ4(sc, CS4280_PDTC);
- DPRINTF(("pctl=0x%08x pfie=0x%08x pba=0x%08x pdtc=0x%08x\n",
- pctl, pfie, pba, pdtc));
- }
-
- /* save current capture status */
- if (sc->sc_rrun) {
- cctl = BA1READ4(sc, CS4280_CCTL);
- cie = BA1READ4(sc, CS4280_CIE);
- cba = BA1READ4(sc, CS4280_CBA);
- DPRINTF(("cctl=0x%08x cie=0x%08x cba=0x%08x\n",
- cctl, cie, cba));
- }
+ struct cs428x_softc *sc = device_private(dv);
+
+ if (sc->sc_prun) {
+ sc->sc_suspend_state.cs4280.pctl = BA1READ4(sc, CS4280_PCTL);
+ sc->sc_suspend_state.cs4280.pfie = BA1READ4(sc, CS4280_PFIE);
+ sc->sc_suspend_state.cs4280.pba = BA1READ4(sc, CS4280_PBA);
+ sc->sc_suspend_state.cs4280.pdtc = BA1READ4(sc, CS4280_PDTC);
+ DPRINTF(("pctl=0x%08x pfie=0x%08x pba=0x%08x pdtc=0x%08x\n",
+ sc->sc_suspend_state.cs4280.pctl,
+ sc->sc_suspend_state.cs4280.pfie,
+ sc->sc_suspend_state.cs4280.pba,
+ sc->sc_suspend_state.cs4280.pdtc));
+ }
- /* Stop DMA */
- BA1WRITE4(sc, CS4280_PCTL, pctl & ~PCTL_MASK);
- BA1WRITE4(sc, CS4280_CCTL, BA1READ4(sc, CS4280_CCTL) & ~CCTL_MASK);
+ /* save current capture status */
+ if (sc->sc_rrun) {
+ sc->sc_suspend_state.cs4280.cctl = BA1READ4(sc, CS4280_CCTL);
+ sc->sc_suspend_state.cs4280.cie = BA1READ4(sc, CS4280_CIE);
+ sc->sc_suspend_state.cs4280.cba = BA1READ4(sc, CS4280_CBA);
+ DPRINTF(("cctl=0x%08x cie=0x%08x cba=0x%08x\n",
+ sc->sc_suspend_state.cs4280.cctl,
+ sc->sc_suspend_state.cs4280.cie,
+ sc->sc_suspend_state.cs4280.cba));
+ }
- pci_conf_capture(sc->sc_pc, sc->sc_pt, &sc->sc_pciconf);
- if (sc->sc_ih != NULL)
- pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
+ /* Stop DMA */
+ BA1WRITE4(sc, CS4280_PCTL, sc->sc_suspend_state.cs4280.pctl & ~PCTL_MASK);
+ BA1WRITE4(sc, CS4280_CCTL, BA1READ4(sc, CS4280_CCTL) & ~CCTL_MASK);
- break;
- case PWR_RESUME:
- if (sc->sc_suspend == PWR_RESUME) {
- printf("cs4280_power: odd, resume without suspend.\n");
- sc->sc_suspend = why;
- return;
- }
+ return true;
+}
- sc->sc_ih = pci_intr_establish(sc->sc_pc, sc->intrh,
- IPL_AUDIO, cs4280_intr, sc);
- if (sc->sc_ih == NULL) {
- aprint_error("%s: can't establish interrupt",
- sc->sc_dev.dv_xname);
- /* XXX jmcneill what should we do here? */
- return;
- }
- pci_conf_restore(sc->sc_pc, sc->sc_pt, &sc->sc_pciconf);
+static bool
+cs4280_resume(device_t dv)
+{
+ struct cs428x_softc *sc = device_private(dv);
- sc->sc_suspend = why;
- cs4280_init(sc, 0);
+ cs4280_init(sc, 0);
#if 0
- cs4280_reset_codec(sc);
+ cs4280_reset_codec(sc);
#endif
- /* restore ac97 registers */
- (*sc->codec_if->vtbl->restore_ports)(sc->codec_if);
-
- /* restore DMA related status */
- if(sc->sc_prun) {
- DPRINTF(("pctl=0x%08x pfie=0x%08x pba=0x%08x pdtc=0x%08x\n",
- pctl, pfie, pba, pdtc));
- cs4280_set_dac_rate(sc, sc->sc_prate);
- BA1WRITE4(sc, CS4280_PDTC, pdtc);
- BA1WRITE4(sc, CS4280_PBA, pba);
- BA1WRITE4(sc, CS4280_PFIE, pfie);
- BA1WRITE4(sc, CS4280_PCTL, pctl);
- }
+ /* restore ac97 registers */
+ (*sc->codec_if->vtbl->restore_ports)(sc->codec_if);
+
+ /* restore DMA related status */
+ if(sc->sc_prun) {
+ DPRINTF(("pctl=0x%08x pfie=0x%08x pba=0x%08x pdtc=0x%08x\n",
+ sc->sc_suspend_state.cs4280.pctl,
+ sc->sc_suspend_state.cs4280.pfie,
+ sc->sc_suspend_state.cs4280.pba,
+ sc->sc_suspend_state.cs4280.pdtc));
+ cs4280_set_dac_rate(sc, sc->sc_prate);
+ BA1WRITE4(sc, CS4280_PDTC, sc->sc_suspend_state.cs4280.pdtc);
+ BA1WRITE4(sc, CS4280_PBA, sc->sc_suspend_state.cs4280.pba);
+ BA1WRITE4(sc, CS4280_PFIE, sc->sc_suspend_state.cs4280.pfie);
+ BA1WRITE4(sc, CS4280_PCTL, sc->sc_suspend_state.cs4280.pctl);
+ }
- if (sc->sc_rrun) {
- DPRINTF(("cctl=0x%08x cie=0x%08x cba=0x%08x\n",
- cctl, cie, cba));
- cs4280_set_adc_rate(sc, sc->sc_rrate);
- BA1WRITE4(sc, CS4280_CBA, cba);
- BA1WRITE4(sc, CS4280_CIE, cie);
- BA1WRITE4(sc, CS4280_CCTL, cctl);
- }
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
+ if (sc->sc_rrun) {
+ DPRINTF(("cctl=0x%08x cie=0x%08x cba=0x%08x\n",
+ sc->sc_suspend_state.cs4280.cctl,
+ sc->sc_suspend_state.cs4280.cie,
+ sc->sc_suspend_state.cs4280.cba));
+ cs4280_set_adc_rate(sc, sc->sc_rrate);
+ BA1WRITE4(sc, CS4280_CBA, sc->sc_suspend_state.cs4280.cba);
+ BA1WRITE4(sc, CS4280_CIE, sc->sc_suspend_state.cs4280.cie);
+ BA1WRITE4(sc, CS4280_CCTL, sc->sc_suspend_state.cs4280.cctl);
}
+
+ return true;
}
static int
diff --git a/sys/dev/pci/cs4281.c b/sys/dev/pci/cs4281.c
index bf4e8ec5713..3e32a67213b 100644
--- a/sys/dev/pci/cs4281.c
+++ b/sys/dev/pci/cs4281.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cs4281.c,v 1.35 2007/10/19 12:00:41 ad Exp $ */
+/* $NetBSD: cs4281.c,v 1.36 2007/12/09 20:28:07 jmcneill 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.35 2007/10/19 12:00:41 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cs4281.c,v 1.36 2007/12/09 20:28:07 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -106,7 +106,8 @@ static void cs4281_set_adc_rate(struct cs428x_softc *, int);
static int cs4281_init(struct cs428x_softc *, int);
/* Power Management */
-static void cs4281_power(int, void *);
+static bool cs4281_suspend(device_t);
+static bool cs4281_resume(device_t);
static const struct audio_hw_if cs4281_hw_if = {
NULL, /* open */
@@ -292,9 +293,8 @@ cs4281_attach(struct device *parent, struct device *self, void *aux)
midi_attach_mi(&cs4281_midi_hw_if, sc, &sc->sc_dev);
#endif
- sc->sc_suspend = PWR_RESUME;
- sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- cs4281_power, sc);
+ if (!pmf_device_register(self, cs4281_suspend, cs4281_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
@@ -721,93 +721,64 @@ cs4281_trigger_input(void *addr, void *start, void *end, int blksize,
return 0;
}
-/* Power Hook */
-static void
-cs4281_power(int why, void *v)
+static bool
+cs4281_suspend(device_t dv)
{
- static uint32_t dba0 = 0, dbc0 = 0, dmr0 = 0, dcr0 = 0;
- static uint32_t dba1 = 0, dbc1 = 0, dmr1 = 0, dcr1 = 0;
- struct cs428x_softc *sc;
-
- sc = (struct cs428x_softc *)v;
- DPRINTF(("%s: cs4281_power why=%d\n", sc->sc_dev.dv_xname, why));
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- sc->sc_suspend = why;
-
- /* save current playback status */
- if (sc->sc_prun) {
- dcr0 = BA0READ4(sc, CS4281_DCR0);
- dmr0 = BA0READ4(sc, CS4281_DMR0);
- dbc0 = BA0READ4(sc, CS4281_DBC0);
- dba0 = BA0READ4(sc, CS4281_DBA0);
- }
-
- /* save current capture status */
- if (sc->sc_rrun) {
- dcr1 = BA0READ4(sc, CS4281_DCR1);
- dmr1 = BA0READ4(sc, CS4281_DMR1);
- dbc1 = BA0READ4(sc, CS4281_DBC1);
- dba1 = BA0READ4(sc, CS4281_DBA1);
- }
- /* Stop DMA */
- BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) | DCRn_MSK);
- BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) | DCRn_MSK);
+ struct cs428x_softc *sc = device_private(dv);
+
+ /* save current playback status */
+ if (sc->sc_prun) {
+ sc->sc_suspend_state.cs4281.dcr0 = BA0READ4(sc, CS4281_DCR0);
+ sc->sc_suspend_state.cs4281.dmr0 = BA0READ4(sc, CS4281_DMR0);
+ sc->sc_suspend_state.cs4281.dbc0 = BA0READ4(sc, CS4281_DBC0);
+ sc->sc_suspend_state.cs4281.dba0 = BA0READ4(sc, CS4281_DBA0);
+ }
- pci_conf_capture(sc->sc_pc, sc->sc_pt, &sc->sc_pciconf);
- if (sc->sc_ih != NULL)
- pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
+ /* save current capture status */
+ if (sc->sc_rrun) {
+ sc->sc_suspend_state.cs4281.dcr1 = BA0READ4(sc, CS4281_DCR1);
+ sc->sc_suspend_state.cs4281.dmr1 = BA0READ4(sc, CS4281_DMR1);
+ sc->sc_suspend_state.cs4281.dbc1 = BA0READ4(sc, CS4281_DBC1);
+ sc->sc_suspend_state.cs4281.dba1 = BA0READ4(sc, CS4281_DBA1);
+ }
+ /* Stop DMA */
+ BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) | DCRn_MSK);
+ BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) | DCRn_MSK);
- break;
- case PWR_RESUME:
- if (sc->sc_suspend == PWR_RESUME) {
- printf("cs4281_power: odd, resume without suspend.\n");
- sc->sc_suspend = why;
- return;
- }
+ return true;
+}
- sc->sc_ih = pci_intr_establish(sc->sc_pc, sc->intrh,
- IPL_AUDIO, cs4281_intr, sc);
- if (sc->sc_ih == NULL) {
- aprint_error("%s: can't establish interrupt",
- sc->sc_dev.dv_xname);
- /* XXX jmcneill what should we do here? */
- return;
- }
- pci_conf_restore(sc->sc_pc, sc->sc_pt, &sc->sc_pciconf);
+static bool
+cs4281_resume(device_t dv)
+{
+ struct cs428x_softc *sc = device_private(dv);
- sc->sc_suspend = why;
- cs4281_init(sc, 0);
- cs4281_reset_codec(sc);
+ cs4281_init(sc, 0);
+ cs4281_reset_codec(sc);
- /* restore ac97 registers */
- (*sc->codec_if->vtbl->restore_ports)(sc->codec_if);
+ /* restore ac97 registers */
+ (*sc->codec_if->vtbl->restore_ports)(sc->codec_if);
- /* restore DMA related status */
- if (sc->sc_prun) {
- cs4281_set_dac_rate(sc, sc->sc_prate);
- BA0WRITE4(sc, CS4281_DBA0, dba0);
- BA0WRITE4(sc, CS4281_DBC0, dbc0);
- BA0WRITE4(sc, CS4281_DMR0, dmr0);
- BA0WRITE4(sc, CS4281_DCR0, dcr0);
- }
- if (sc->sc_rrun) {
- cs4281_set_adc_rate(sc, sc->sc_rrate);
- BA0WRITE4(sc, CS4281_DBA1, dba1);
- BA0WRITE4(sc, CS4281_DBC1, dbc1);
- BA0WRITE4(sc, CS4281_DMR1, dmr1);
- BA0WRITE4(sc, CS4281_DCR1, dcr1);
- }
- /* enable intterupts */
- if (sc->sc_prun || sc->sc_rrun)
- BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM);
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
+ /* restore DMA related status */
+ if (sc->sc_prun) {
+ cs4281_set_dac_rate(sc, sc->sc_prate);
+ BA0WRITE4(sc, CS4281_DBA0, sc->sc_suspend_state.cs4281.dba0);
+ BA0WRITE4(sc, CS4281_DBC0, sc->sc_suspend_state.cs4281.dbc0);
+ BA0WRITE4(sc, CS4281_DMR0, sc->sc_suspend_state.cs4281.dmr0);
+ BA0WRITE4(sc, CS4281_DCR0, sc->sc_suspend_state.cs4281.dcr0);
+ }
+ if (sc->sc_rrun) {
+ cs4281_set_adc_rate(sc, sc->sc_rrate);
+ BA0WRITE4(sc, CS4281_DBA1, sc->sc_suspend_state.cs4281.dba1);
+ BA0WRITE4(sc, CS4281_DBC1, sc->sc_suspend_state.cs4281.dbc1);
+ BA0WRITE4(sc, CS4281_DMR1, sc->sc_suspend_state.cs4281.dmr1);
+ BA0WRITE4(sc, CS4281_DCR1, sc->sc_suspend_state.cs4281.dcr1);
}
+ /* enable intterupts */
+ if (sc->sc_prun || sc->sc_rrun)
+ BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM);
+
+ return true;
}
/* control AC97 codec */
diff --git a/sys/dev/pci/cs428x.h b/sys/dev/pci/cs428x.h
index ef5e180e667..97cffe2a79b 100644
--- a/sys/dev/pci/cs428x.h
+++ b/sys/dev/pci/cs428x.h
@@ -1,4 +1,4 @@
-/* $NetBSD: cs428x.h,v 1.13 2007/06/15 13:26:57 joerg Exp $ */
+/* $NetBSD: cs428x.h,v 1.14 2007/12/09 20:28:07 jmcneill Exp $ */
/*
* Copyright (c) 2000 Tatoku Ogaito. All rights reserved.
@@ -141,9 +141,27 @@ struct cs428x_softc {
struct ac97_host_if host_if;
/* Power Management */
- char sc_suspend;
- void *sc_powerhook; /* Power Hook */
- struct pci_conf_state sc_pciconf;
+ union {
+ struct {
+ uint32_t pctl;
+ uint32_t pba;
+ uint32_t pfie;
+ uint32_t pdtc;
+ uint32_t cctl;
+ uint32_t cba;
+ uint32_t cie;
+ } cs4280;
+ struct {
+ uint32_t dba0;
+ uint32_t dbc0;
+ uint32_t dmr0;
+ uint32_t dcr0;
+ uint32_t dba1;
+ uint32_t dbc1;
+ uint32_t dmr1;
+ uint32_t dcr1;
+ } cs4281;
+ } sc_suspend_state;
/* CLKRUN hack (CS428X_FLAG_CLKRUN), only for CS4280 */
int sc_active;
diff --git a/sys/dev/pci/ehci_pci.c b/sys/dev/pci/ehci_pci.c
index 9d8d06cbdb9..943144bf4a2 100644
--- a/sys/dev/pci/ehci_pci.c
+++ b/sys/dev/pci/ehci_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ehci_pci.c,v 1.31 2007/10/19 12:00:43 ad Exp $ */
+/* $NetBSD: ehci_pci.c,v 1.32 2007/12/09 20:28:07 jmcneill Exp $ */
/*
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci_pci.c,v 1.31 2007/10/19 12:00:43 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci_pci.c,v 1.32 2007/12/09 20:28:07 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -69,16 +69,13 @@ extern int ehcidebug;
static void ehci_get_ownership(ehci_softc_t *sc, pci_chipset_tag_t pc,
pcitag_t tag);
-static void ehci_pci_powerhook(int, void *);
+static bool ehci_pci_resume(device_t);
struct ehci_pci_softc {
ehci_softc_t sc;
pci_chipset_tag_t sc_pc;
pcitag_t sc_tag;
void *sc_ih; /* interrupt vectoring */
-
- void *sc_powerhook;
- struct pci_conf_state sc_pciconf;
};
#define EHCI_MAX_BIOS_WAIT 1000 /* ms */
@@ -210,21 +207,15 @@ ehci_pci_attach(struct device *parent, struct device *self, void *aux)
ehci_get_ownership(&sc->sc, pc, tag);
- /*
- * Establish our powerhook before ehci_init() does its powerhook.
- */
- sc->sc_powerhook = powerhook_establish(
- USBDEVNAME(sc->sc.sc_bus.bdev) , ehci_pci_powerhook, sc);
- if (sc->sc_powerhook == NULL)
- aprint_error("%s: couldn't establish powerhook\n",
- devname);
-
r = ehci_init(&sc->sc);
if (r != USBD_NORMAL_COMPLETION) {
aprint_error("%s: init failed, error=%d\n", devname, r);
return;
}
+ if (!pmf_device_register(self, ehci_suspend, ehci_pci_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
/* Attach usb device. */
sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus,
usbctlprint);
@@ -236,9 +227,7 @@ ehci_pci_detach(device_ptr_t self, int flags)
struct ehci_pci_softc *sc = (struct ehci_pci_softc *)self;
int rv;
- if (sc->sc_powerhook != NULL)
- powerhook_disestablish(sc->sc_powerhook);
-
+ pmf_device_deregister(self);
rv = ehci_detach(&sc->sc, flags);
if (rv)
return (rv);
@@ -336,27 +325,11 @@ ehci_get_ownership(ehci_softc_t *sc, pci_chipset_tag_t pc, pcitag_t tag)
}
}
-static void
-ehci_pci_powerhook(int why, void *opaque)
+static bool
+ehci_pci_resume(device_t dv)
{
- struct ehci_pci_softc *sc;
- pci_chipset_tag_t pc;
- pcitag_t tag;
-
- sc = (struct ehci_pci_softc *)opaque;
- pc = sc->sc_pc;
- tag = sc->sc_tag;
-
- switch (why) {
- case PWR_STANDBY:
- case PWR_SUSPEND:
- pci_conf_capture(pc, tag, &sc->sc_pciconf);
- break;
- case PWR_RESUME:
- pci_conf_restore(pc, tag, &sc->sc_pciconf);
- ehci_get_ownership(&sc->sc, pc, tag);
- break;
- }
+ struct ehci_pci_softc *sc = device_private(dv);
- return;
+ ehci_get_ownership(&sc->sc, sc->sc_pc, sc->sc_tag);
+ return ehci_resume(dv);
}
diff --git a/sys/dev/pci/esa.c b/sys/dev/pci/esa.c
index 396a56bd2e4..33ba3304cad 100644
--- a/sys/dev/pci/esa.c
+++ b/sys/dev/pci/esa.c
@@ -1,4 +1,4 @@
-/* $NetBSD: esa.c,v 1.42 2007/10/19 12:00:43 ad Exp $ */
+/* $NetBSD: esa.c,v 1.43 2007/12/09 20:28:07 jmcneill Exp $ */
/*
* Copyright (c) 2001, 2002, 2006 Jared D. McNeill <jmcneill@invisible.ca>
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: esa.c,v 1.42 2007/10/19 12:00:43 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: esa.c,v 1.43 2007/12/09 20:28:07 jmcneill Exp $");
#include <sys/types.h>
#include <sys/errno.h>
@@ -162,9 +162,8 @@ static void esa_remove_list(struct esa_voice *, struct esa_list *,
int);
/* power management */
-static void esa_powerhook(int, void *);
-static int esa_suspend(struct esa_softc *);
-static int esa_resume(struct esa_softc *);
+static bool esa_suspend(device_t);
+static bool esa_resume(device_t);
#define ESA_NENCODINGS 8
@@ -1136,11 +1135,8 @@ esa_attach(struct device *parent, struct device *self, void *aux)
audio_attach_mi(&esa_hw_if, &sc->voice[i], &sc->sc_dev);
}
- sc->powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- esa_powerhook, sc);
- if (sc->powerhook == NULL)
- aprint_error("%s: WARNING: unable to establish powerhook\n",
- sc->sc_dev.dv_xname);
+ if (!pmf_device_register(self, esa_suspend, esa_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
return;
}
@@ -1637,33 +1633,14 @@ esa_remove_list(struct esa_voice *vc, struct esa_list *el, int index)
return;
}
-static void
-esa_powerhook(int why, void *hdl)
-{
- struct esa_softc *sc;
-
- sc = (struct esa_softc *)hdl;
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- esa_suspend(sc);
- break;
- case PWR_RESUME:
- esa_resume(sc);
- sc->codec_if->vtbl->restore_ports(sc->codec_if);
- break;
- }
-}
-
-static int
-esa_suspend(struct esa_softc *sc)
+static bool
+esa_suspend(device_t dv)
{
- bus_space_tag_t iot;
- bus_space_handle_t ioh;
+ struct esa_softc *sc = device_private(dv);
+ bus_space_tag_t iot = sc->sc_iot;
+ bus_space_handle_t ioh = sc->sc_ioh;
int i, index;
- iot = sc->sc_iot;
- ioh = sc->sc_ioh;
index = 0;
bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL, 0);
@@ -1681,19 +1658,18 @@ esa_suspend(struct esa_softc *sc)
sc->savemem[index++] = esa_read_assp(sc,
ESA_MEMTYPE_INTERNAL_DATA, i);
- return 0;
+ return true;
}
-static int
-esa_resume(struct esa_softc *sc)
+static bool
+esa_resume(device_t dv)
{
- bus_space_tag_t iot;
- bus_space_handle_t ioh;
+ struct esa_softc *sc = device_private(dv);
+ bus_space_tag_t iot = sc->sc_iot;
+ bus_space_handle_t ioh = sc->sc_ioh;
int i, index;
uint8_t reset_state;
- iot = sc->sc_iot;
- ioh = sc->sc_ioh;
index = 0;
delay(10000);
@@ -1721,7 +1697,7 @@ esa_resume(struct esa_softc *sc)
esa_enable_interrupts(sc);
esa_amp_enable(sc);
- return 0;
+ return true;
}
static uint32_t
diff --git a/sys/dev/pci/esavar.h b/sys/dev/pci/esavar.h
index bc725c238e3..6e065c14cc8 100644
--- a/sys/dev/pci/esavar.h
+++ b/sys/dev/pci/esavar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: esavar.h,v 1.8 2007/03/04 06:02:18 christos Exp $ */
+/* $NetBSD: esavar.h,v 1.9 2007/12/09 20:28:07 jmcneill Exp $ */
/*
* Copyright (c) 2001, 2002 Jared D. McNeill <jmcneill@invisible.ca>
@@ -132,6 +132,5 @@ struct esa_softc
int type; /* Allegro-1 or Maestro 3? */
int delay1, delay2;
- void *powerhook;
uint16_t *savemem;
};
diff --git a/sys/dev/pci/esm.c b/sys/dev/pci/esm.c
index af6f11e37fa..25d90204b00 100644
--- a/sys/dev/pci/esm.c
+++ b/sys/dev/pci/esm.c
@@ -1,4 +1,4 @@
-/* $NetBSD: esm.c,v 1.43 2007/10/19 12:00:43 ad Exp $ */
+/* $NetBSD: esm.c,v 1.44 2007/12/09 20:28:07 jmcneill Exp $ */
/*-
* Copyright (c) 2002, 2003 Matt Fredette
@@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: esm.c,v 1.43 2007/10/19 12:00:43 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: esm.c,v 1.44 2007/12/09 20:28:07 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -146,8 +146,8 @@ static void esmch_set_format(struct esm_chinfo *,
static void esmch_combine_input(struct esm_softc *,
struct esm_chinfo *);
-/* Power Management */
-void esm_powerhook(int, void *);
+static bool esm_suspend(device_t);
+static bool esm_resume(device_t);
CFATTACH_DECL(esm, sizeof(struct esm_softc),
esm_match, esm_attach, NULL, NULL);
@@ -1700,39 +1700,14 @@ esm_attach(struct device *parent, struct device *self, void *aux)
audio_attach_mi(&esm_hw_if, self, &ess->sc_dev);
- ess->esm_suspend = PWR_RESUME;
- ess->esm_powerhook = powerhook_establish(ess->sc_dev.dv_xname,
- esm_powerhook, ess);
+ if (!pmf_device_register(self, esm_suspend, esm_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
-/* Power Hook */
-void
-esm_powerhook(int why, void *v)
-{
- struct esm_softc *ess;
-
- ess = (struct esm_softc *)v;
- DPRINTF(ESM_DEBUG_PARAM,
- ("%s: ESS maestro 2E why=%d\n", ess->sc_dev.dv_xname, why));
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- ess->esm_suspend = why;
- esm_suspend(ess);
- DPRINTF(ESM_DEBUG_RESUME, ("esm_suspend\n"));
- break;
-
- case PWR_RESUME:
- ess->esm_suspend = why;
- esm_resume(ess);
- DPRINTF(ESM_DEBUG_RESUME, ("esm_resumed\n"));
- break;
- }
-}
-
-int
-esm_suspend(struct esm_softc *ess)
+static bool
+esm_suspend(device_t dv)
{
+ struct esm_softc *ess = device_private(dv);
int x;
x = splaudio();
@@ -1749,12 +1724,13 @@ esm_suspend(struct esm_softc *ess)
bus_space_write_4(ess->st, ess->sh, PORT_RINGBUS_CTRL, 0);
delay(1);
- return 0;
+ return true;
}
-int
-esm_resume(struct esm_softc *ess)
+static bool
+esm_resume(device_t dv)
{
+ struct esm_softc *ess = device_private(dv);
int x;
uint16_t pcmbar;
@@ -1787,21 +1763,6 @@ esm_resume(struct esm_softc *ess)
wp_starttimer(ess);
}
splx(x);
- return 0;
-}
-
-#if 0
-int
-esm_shutdown(struct esm_softc *ess)
-{
- int i;
-
- wp_stoptimer(ess);
- bus_space_write_2(ess->st, ess->sh, PORT_HOSTINT_CTRL, 0);
- esm_halt_output(ess);
- esm_halt_input(ess);
-
- return 0;
+ return true;
}
-#endif
diff --git a/sys/dev/pci/esmvar.h b/sys/dev/pci/esmvar.h
index 38ce882e0ce..188e1488b39 100644
--- a/sys/dev/pci/esmvar.h
+++ b/sys/dev/pci/esmvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: esmvar.h,v 1.14 2007/03/04 06:02:18 christos Exp $ */
+/* $NetBSD: esmvar.h,v 1.15 2007/12/09 20:28:08 jmcneill Exp $ */
/*-
* Copyright (c) 2002, 2003 Matt Fredette
@@ -178,10 +178,6 @@ struct esm_softc {
void (*sc_rintr)(void *);
void *sc_rarg;
-
- /* Power Management */
- char esm_suspend;
- void *esm_powerhook;
};
enum esm_quirk_flags {
@@ -202,7 +198,6 @@ int esm_attach_codec(void *, struct ac97_codec_if *);
int esm_reset_codec(void *);
enum ac97_host_flags esm_flags_codec(void *);
-void esm_power(struct esm_softc *, int);
void esm_init(struct esm_softc *);
void esm_initcodec(struct esm_softc *);
@@ -235,8 +230,4 @@ int esm_intr(void *);
int esm_allocmem(struct esm_softc *, size_t, size_t,
struct esm_dma *);
-int esm_suspend(struct esm_softc *);
-int esm_resume(struct esm_softc *);
-int esm_shutdown(struct esm_softc *);
-
enum esm_quirk_flags esm_get_quirks(pcireg_t);
diff --git a/sys/dev/pci/fwohci_pci.c b/sys/dev/pci/fwohci_pci.c
index 9703d4e76aa..1c7c9719626 100644
--- a/sys/dev/pci/fwohci_pci.c
+++ b/sys/dev/pci/fwohci_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fwohci_pci.c,v 1.27 2007/11/06 15:24:10 kiyohara Exp $ */
+/* $NetBSD: fwohci_pci.c,v 1.28 2007/12/09 20:28:08 jmcneill Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fwohci_pci.c,v 1.27 2007/11/06 15:24:10 kiyohara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fwohci_pci.c,v 1.28 2007/12/09 20:28:08 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -62,17 +62,15 @@ struct fwohci_pci_softc {
pci_chipset_tag_t psc_pc;
pcitag_t psc_tag;
- struct pci_conf_state psc_pciconf;
void *psc_ih;
- void *psc_shutdownhook;
- void *psc_powerhook;
};
static int fwohci_pci_match(struct device *, struct cfdata *, void *);
static void fwohci_pci_attach(struct device *, struct device *, void *);
-static void fwohci_pci_shutdown(void *);
-static void fwohci_pci_power(int, void *);
+
+static bool fwohci_pci_suspend(device_t);
+static bool fwohci_pci_resume(device_t);
CFATTACH_DECL(fwohci_pci, sizeof(struct fwohci_pci_softc),
fwohci_pci_match, fwohci_pci_attach, NULL, NULL);
@@ -118,7 +116,7 @@ fwohci_pci_attach(struct device *parent, struct device *self,
NULL, &psc->psc_sc.bssize)) {
aprint_error("%s: can't map OHCI register space\n",
self->dv_xname);
- return;
+ goto fail;
}
/* Disable interrupts, so we don't get any spurious ones. */
@@ -132,7 +130,7 @@ fwohci_pci_attach(struct device *parent, struct device *self,
/* Map and establish the interrupt. */
if (pci_intr_map(pa, &ih)) {
aprint_error("%s: couldn't map interrupt\n", self->dv_xname);
- return;
+ goto fail;
}
intrstr = pci_intr_string(pa->pa_pc, ih);
psc->psc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, fwohci_filt,
@@ -143,57 +141,51 @@ fwohci_pci_attach(struct device *parent, struct device *self,
if (intrstr != NULL)
aprint_normal(" at %s", intrstr);
aprint_normal("\n");
- return;
+ goto fail;
}
aprint_normal("%s: interrupting at %s\n", self->dv_xname, intrstr);
- psc->psc_shutdownhook =
- shutdownhook_establish(fwohci_pci_shutdown, psc);
- psc->psc_powerhook =
- powerhook_establish(self->dv_xname, fwohci_pci_power, psc);
+ if (!pmf_device_register(self, fwohci_pci_suspend, fwohci_pci_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
if (fwohci_init(&(psc->psc_sc), &(psc->psc_sc.fc._dev)) != 0) {
pci_intr_disestablish(pa->pa_pc, psc->psc_ih);
bus_space_unmap(psc->psc_sc.bst, psc->psc_sc.bsh,
psc->psc_sc.bssize);
}
+
+ return;
+
+fail:
+ /* In the event that we fail to attach, register a null pnp handler */
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
+ return;
}
-static void
-fwohci_pci_shutdown(void *arg)
+static bool
+fwohci_pci_suspend(device_t dv)
{
- struct fwohci_pci_softc *psc = arg;
+ struct fwohci_pci_softc *psc = device_private(dv);
+ int s;
+ s = splbio();
fwohci_stop(&psc->psc_sc, psc->psc_sc.fc.dev);
+ splx(s);
+
+ return true;
}
-static void
-fwohci_pci_power(int why, void *arg)
+static bool
+fwohci_pci_resume(device_t dv)
{
- struct fwohci_pci_softc *psc = arg;
+ struct fwohci_pci_softc *psc = device_private(dv);
int s;
s = splbio();
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- printf("%s: suspending...\n", psc->psc_sc.fc._dev.dv_xname);
-
- pci_conf_capture(psc->psc_pc, psc->psc_tag, &psc->psc_pciconf);
- fwohci_stop(&psc->psc_sc, psc->psc_sc.fc.dev);
- break;
-
- case PWR_RESUME:
- printf("%s: resuming...\n", psc->psc_sc.fc._dev.dv_xname);
-
- pci_conf_restore(psc->psc_pc, psc->psc_tag, &psc->psc_pciconf);
- fwohci_resume(&psc->psc_sc, psc->psc_sc.fc.dev);
- break;
-
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
- }
+ fwohci_resume(&psc->psc_sc, psc->psc_sc.fc.dev);
splx(s);
+
+ return true;
}
diff --git a/sys/dev/pci/ichsmb.c b/sys/dev/pci/ichsmb.c
index bcd13d04aef..7f210d61693 100644
--- a/sys/dev/pci/ichsmb.c
+++ b/sys/dev/pci/ichsmb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ichsmb.c,v 1.10 2007/10/19 12:00:44 ad Exp $ */
+/* $NetBSD: ichsmb.c,v 1.11 2007/12/09 20:28:08 jmcneill Exp $ */
/* $OpenBSD: ichiic.c,v 1.18 2007/05/03 09:36:26 dlg Exp $ */
/*
@@ -22,7 +22,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ichsmb.c,v 1.10 2007/10/19 12:00:44 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ichsmb.c,v 1.11 2007/12/09 20:28:08 jmcneill Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -175,7 +175,8 @@ ichsmb_attach(struct device *parent, struct device *self, void *aux)
iba.iba_tag = &sc->sc_i2c_tag;
config_found(self, &iba, iicbus_print);
- return;
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/pci/if_an_pci.c b/sys/dev/pci/if_an_pci.c
index 083974a0525..41ddad4aa46 100644
--- a/sys/dev/pci/if_an_pci.c
+++ b/sys/dev/pci/if_an_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_an_pci.c,v 1.23 2007/10/19 12:00:44 ad Exp $ */
+/* $NetBSD: if_an_pci.c,v 1.24 2007/12/09 20:28:08 jmcneill Exp $ */
/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_an_pci.c,v 1.23 2007/10/19 12:00:44 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_an_pci.c,v 1.24 2007/12/09 20:28:08 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -81,6 +81,8 @@ __KERNEL_RCSID(0, "$NetBSD: if_an_pci.c,v 1.23 2007/10/19 12:00:44 ad Exp $");
struct an_pci_softc {
struct an_softc sc_an; /* real "an" softc */
+ pci_chipset_tag_t sc_pct;
+ pcitag_t sc_pcitag;
/* PCI-specific goo. */
void *sc_ih; /* interrupt handle */
@@ -130,6 +132,9 @@ an_pci_attach(struct device *parent, struct device *self, void *aux)
bus_size_t iosize;
u_int32_t csr;
+ psc->sc_pct = pa->pa_pc;
+ psc->sc_pcitag = pa->pa_tag;
+
aprint_naive(": 802.11 controller\n");
pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
@@ -171,4 +176,9 @@ an_pci_attach(struct device *parent, struct device *self, void *aux)
pci_intr_disestablish(pa->pa_pc, psc->sc_ih);
bus_space_unmap(sc->sc_iot, sc->sc_ioh, iosize);
}
+
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, &sc->sc_if);
}
diff --git a/sys/dev/pci/if_ath_pci.c b/sys/dev/pci/if_ath_pci.c
index 3516ee7056c..2445df619f0 100644
--- a/sys/dev/pci/if_ath_pci.c
+++ b/sys/dev/pci/if_ath_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ath_pci.c,v 1.21 2007/04/17 21:50:31 dyoung Exp $ */
+/* $NetBSD: if_ath_pci.c,v 1.22 2007/12/09 20:28:08 jmcneill Exp $ */
/*-
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
@@ -41,7 +41,7 @@
__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath_pci.c,v 1.11 2005/01/18 18:08:16 sam Exp $");
#endif
#ifdef __NetBSD__
-__KERNEL_RCSID(0, "$NetBSD: if_ath_pci.c,v 1.21 2007/04/17 21:50:31 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ath_pci.c,v 1.22 2007/12/09 20:28:08 jmcneill Exp $");
#endif
/*
@@ -84,22 +84,16 @@ struct ath_pci_softc {
struct ath_softc sc_sc;
pci_chipset_tag_t sc_pc;
pcitag_t sc_pcitag;
- struct pci_conf_state sc_pciconf;
void *sc_ih; /* interrupt handler */
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
- void *sc_sdhook;
};
#define BS_BAR 0x10
-#define PCIR_RETRY_TIMEOUT_REG 0x40
-#define PCIR_RETRY_TIMEOUT_MASK __BITS(15,8)
static void ath_pci_attach(struct device *, struct device *, void *);
static int ath_pci_detach(struct device *, int);
static int ath_pci_match(struct device *, struct cfdata *, void *);
-static void ath_pci_shutdown(void *);
-static void ath_pci_powerhook(int, void *);
static int ath_pci_detach(struct device *, int);
CFATTACH_DECL(ath_pci,
@@ -109,8 +103,6 @@ CFATTACH_DECL(ath_pci,
ath_pci_detach,
NULL);
-static int ath_pci_setup(struct pci_attach_args *);
-
static int
ath_pci_match(struct device *parent, struct cfdata *match, void *aux)
{
@@ -123,34 +115,28 @@ ath_pci_match(struct device *parent, struct cfdata *match, void *aux)
return 0;
}
-static void
-ath_disable_retry(pci_chipset_tag_t pc, pcitag_t tag)
+static bool
+ath_pci_resume(device_t dv)
{
-#if 0
- pcireg_t retry;
+ struct ath_pci_softc *sc = device_private(dv);
- /*
- * Disable retry timeout to keep PCI Tx retries from
- * interfering with ACPI C3 CPU state.
- */
- retry = pci_conf_read(pc, tag, PCIR_RETRY_TIMEOUT_REG);
- pci_conf_write(pc, tag, PCIR_RETRY_TIMEOUT_REG,
- retry & ~PCIR_RETRY_TIMEOUT_MASK);
-#endif
+ pci_disable_retry(sc->sc_pc, sc->sc_pcitag);
+ ath_resume(&sc->sc_sc);
+
+ return true;
}
static int
-ath_pci_setup(struct pci_attach_args *pa)
+ath_pci_setup(struct ath_pci_softc *sc)
{
- pci_chipset_tag_t pc = pa->pa_pc;
pcireg_t bhlc, csr, icr, lattimer;
/*
* Enable memory mapping and bus mastering.
*/
- pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
- pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
- PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE);
- csr = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
+ csr = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
+ csr |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE;
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, csr);
+ csr = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
if ((csr & PCI_COMMAND_MEM_ENABLE) == 0) {
aprint_error("couldn't enable memory mapping\n");
@@ -161,7 +147,7 @@ ath_pci_setup(struct pci_attach_args *pa)
return 0;
}
- ath_disable_retry(pc, pa->pa_tag);
+ pci_disable_retry(sc->sc_pc, sc->sc_pcitag);
/*
* XXX Both this comment and code are replicated in
@@ -184,13 +170,13 @@ ath_pci_setup(struct pci_attach_args *pa)
* I never set a Latency Timer less than 0x10, since that
* is what the old code did.
*/
- bhlc = pci_conf_read(pc, pa->pa_tag, PCI_BHLC_REG);
- icr = pci_conf_read(pc, pa->pa_tag, PCI_INTERRUPT_REG);
+ bhlc = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_BHLC_REG);
+ icr = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_INTERRUPT_REG);
lattimer = MAX(0x10, MIN(0xf8, 8 * PCI_MIN_GNT(icr)));
if (PCI_LATTIMER(bhlc) < lattimer) {
bhlc &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT);
bhlc |= (lattimer << PCI_LATTIMER_SHIFT);
- pci_conf_write(pc, pa->pa_tag, PCI_BHLC_REG, bhlc);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, PCI_BHLC_REG, bhlc);
}
return 1;
}
@@ -204,15 +190,14 @@ ath_pci_attach(struct device *parent, struct device *self, void *aux)
pci_chipset_tag_t pc = pa->pa_pc;
pci_intr_handle_t ih;
pcireg_t mem_type;
- void *phook;
const char *intrstr = NULL;
psc->sc_pc = pc;
psc->sc_pcitag = pa->pa_tag;
- if (!ath_pci_setup(pa))
- goto bad;
+ if (!ath_pci_setup(psc))
+ goto bad;
/*
* Setup memory-mapping of PCI registers.
@@ -254,26 +239,15 @@ ath_pci_attach(struct device *parent, struct device *self, void *aux)
sc->sc_dmat = pa->pa_dmat;
- psc->sc_sdhook = shutdownhook_establish(ath_pci_shutdown, psc);
- if (psc->sc_sdhook == NULL) {
- aprint_error("couldn't make shutdown hook\n");
- goto bad3;
- }
-
- phook = powerhook_establish(sc->sc_dev.dv_xname,
- ath_pci_powerhook, psc);
- if (phook == NULL) {
- aprint_error("couldn't make power hook\n");
- goto bad3;
- }
+ if (!pmf_device_register(self, NULL, ath_pci_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, &sc->sc_if);
if (ath_attach(PCI_PRODUCT(pa->pa_id), sc) == 0)
return;
- shutdownhook_disestablish(psc->sc_sdhook);
- powerhook_disestablish(phook);
-
-bad3: pci_intr_disestablish(pc, psc->sc_ih);
+ pci_intr_disestablish(pc, psc->sc_ih);
bad2: /* XXX */
bad1: /* XXX */
bad:
@@ -285,40 +259,9 @@ ath_pci_detach(struct device *self, int flags)
{
struct ath_pci_softc *psc = (struct ath_pci_softc *)self;
- shutdownhook_disestablish(psc->sc_sdhook);
ath_detach(&psc->sc_sc);
+ pmf_device_deregister(self);
pci_intr_disestablish(psc->sc_pc, psc->sc_ih);
return (0);
}
-
-static void
-ath_pci_shutdown(void *self)
-{
- struct ath_pci_softc *psc = (struct ath_pci_softc *)self;
-
- ath_shutdown(&psc->sc_sc);
-}
-
-static void
-ath_pci_powerhook(int why, void *arg)
-{
- struct ath_pci_softc *sc = arg;
- pci_chipset_tag_t pc = sc->sc_pc;
- pcitag_t tag = sc->sc_pcitag;
-
- switch (why) {
- case PWR_SOFTSUSPEND:
- ath_pci_shutdown(sc);
- break;
- case PWR_SUSPEND:
- pci_conf_capture(pc, tag, &sc->sc_pciconf);
- break;
- case PWR_RESUME:
- pci_conf_restore(pc, tag, &sc->sc_pciconf);
- ath_disable_retry(pc, tag);
- break;
- }
-
- return;
-}
diff --git a/sys/dev/pci/if_bge.c b/sys/dev/pci/if_bge.c
index 1f3b28a99db..e5c3d228af4 100644
--- a/sys/dev/pci/if_bge.c
+++ b/sys/dev/pci/if_bge.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bge.c,v 1.140 2007/11/07 00:23:18 ad Exp $ */
+/* $NetBSD: if_bge.c,v 1.141 2007/12/09 20:28:08 jmcneill Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
@@ -79,7 +79,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.140 2007/11/07 00:23:18 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.141 2007/12/09 20:28:08 jmcneill Exp $");
#include "bpfilter.h"
#include "vlan.h"
@@ -183,7 +183,6 @@ static int bge_rxthresh_nodenum;
static int bge_probe(device_t, cfdata_t, void *);
static void bge_attach(device_t, device_t, void *);
-static void bge_powerhook(int, void *);
static void bge_release_resources(struct bge_softc *);
static void bge_txeof(struct bge_softc *);
static void bge_rxeof(struct bge_softc *);
@@ -196,9 +195,8 @@ static int bge_intr(void *);
static void bge_start(struct ifnet *);
static int bge_ioctl(struct ifnet *, u_long, void *);
static int bge_init(struct ifnet *);
-static void bge_stop(struct bge_softc *);
+static void bge_stop(struct ifnet *, int);
static void bge_watchdog(struct ifnet *);
-static void bge_shutdown(void *);
static int bge_ifmedia_upd(struct ifnet *);
static void bge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
@@ -296,41 +294,34 @@ CFATTACH_DECL_NEW(bge, sizeof(struct bge_softc),
static u_int32_t
bge_readmem_ind(struct bge_softc *sc, int off)
{
- struct pci_attach_args *pa = &(sc->bge_pa);
pcireg_t val;
- pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MEMWIN_BASEADDR, off);
- val = pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_MEMWIN_DATA);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_BASEADDR, off);
+ val = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_DATA);
return val;
}
static void
bge_writemem_ind(struct bge_softc *sc, int off, int val)
{
- struct pci_attach_args *pa = &(sc->bge_pa);
-
- pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MEMWIN_BASEADDR, off);
- pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MEMWIN_DATA, val);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_BASEADDR, off);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_DATA, val);
}
#ifdef notdef
static u_int32_t
bge_readreg_ind(struct bge_softc *sc, int off)
{
- struct pci_attach_args *pa = &(sc->bge_pa);
-
- pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_REG_BASEADDR, off);
- return(pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_REG_DATA));
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_REG_BASEADDR, off);
+ return(pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_REG_DATA));
}
#endif
static void
bge_writereg_ind(struct bge_softc *sc, int off, int val)
{
- struct pci_attach_args *pa = &(sc->bge_pa);
-
- pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_REG_BASEADDR, off);
- pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_REG_DATA, val);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_REG_BASEADDR, off);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_REG_DATA, val);
}
#ifdef notdef
@@ -339,12 +330,11 @@ bge_vpd_readbyte(struct bge_softc *sc, int addr)
{
int i;
u_int32_t val;
- struct pci_attach_args *pa = &(sc->bge_pa);
- pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_VPD_ADDR, addr);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_VPD_ADDR, addr);
for (i = 0; i < BGE_TIMEOUT * 10; i++) {
DELAY(10);
- if (pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_VPD_ADDR) &
+ if (pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_VPD_ADDR) &
BGE_VPD_FLAG)
break;
}
@@ -354,7 +344,7 @@ bge_vpd_readbyte(struct bge_softc *sc, int addr)
return(0);
}
- val = pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_VPD_DATA);
+ val = pci_conf_read(sc->sc_pc, sc->sca_pcitag, BGE_PCI_VPD_DATA);
return((val >> ((addr % 4) * 8)) & 0xFF);
}
@@ -1220,11 +1210,10 @@ bge_chipinit(struct bge_softc *sc)
u_int32_t cachesize;
int i;
u_int32_t dma_rw_ctl;
- struct pci_attach_args *pa = &(sc->bge_pa);
/* Set endianness before we access any non-PCI registers. */
- pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MISC_CTL,
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,
BGE_INIT);
/* Set power state to D0. */
@@ -1249,11 +1238,11 @@ bge_chipinit(struct bge_softc *sc)
*/
for (i = BGE_STATS_BLOCK;
i < BGE_STATS_BLOCK_END + 1; i += sizeof(u_int32_t))
- BGE_MEMWIN_WRITE(pa->pa_pc, pa->pa_tag, i, 0);
+ BGE_MEMWIN_WRITE(sc->sc_pc, sc->sc_pcitag, i, 0);
for (i = BGE_STATUS_BLOCK;
i < BGE_STATUS_BLOCK_END + 1; i += sizeof(u_int32_t))
- BGE_MEMWIN_WRITE(pa->pa_pc, pa->pa_tag, i, 0);
+ BGE_MEMWIN_WRITE(sc->sc_pc, sc->sc_pcitag, i, 0);
/* Set up the PCI DMA control register. */
if (sc->bge_pcie) {
@@ -1271,7 +1260,7 @@ bge_chipinit(struct bge_softc *sc)
#define DMA_CTRL_WRITE_PCIE_H20MARK_256 0x00380000
dma_rw_ctl = 0x76000000; /* XXX XXX XXX */;
- device_ctl = pci_conf_read(pa->pa_pc, pa->pa_tag,
+ device_ctl = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
BGE_PCI_CONF_DEV_CTRL);
aprint_debug_dev(sc->bge_dev, "pcie mode=0x%x\n", device_ctl);
@@ -1287,7 +1276,7 @@ bge_chipinit(struct bge_softc *sc)
} else {
dma_rw_ctl |= BGE_PCIDMA_RWCTL_PCIE_WRITE_WATRMARK_128;
}
- } else if (pci_conf_read(pa->pa_pc, pa->pa_tag,BGE_PCI_PCISTATE) &
+ } else if (pci_conf_read(sc->sc_pc, sc->sc_pcitag,BGE_PCI_PCISTATE) &
BGE_PCISTATE_PCI_BUSMODE) {
/* Conventional PCI bus */
DPRINTFN(4, ("(%s: PCI 2.2 DMA setting)\n",
@@ -1335,7 +1324,7 @@ bge_chipinit(struct bge_softc *sc)
}
}
- pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_DMA_RW_CTL, dma_rw_ctl);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_DMA_RW_CTL, dma_rw_ctl);
/*
* Set up general mode register.
@@ -1345,40 +1334,40 @@ bge_chipinit(struct bge_softc *sc)
BGE_MODECTL_TX_NO_PHDR_CSUM|BGE_MODECTL_RX_NO_PHDR_CSUM);
/* Get cache line size. */
- cachesize = pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_CACHESZ);
+ cachesize = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CACHESZ);
/*
* Avoid violating PCI spec on certain chip revs.
*/
- if (pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_CMD) &
+ if (pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD) &
PCIM_CMD_MWIEN) {
switch(cachesize) {
case 1:
- PCI_SETBIT(pa->pa_pc, pa->pa_tag, BGE_PCI_DMA_RW_CTL,
+ PCI_SETBIT(sc->sc_pc, sc->sc_pcitag, BGE_PCI_DMA_RW_CTL,
BGE_PCI_WRITE_BNDRY_16BYTES);
break;
case 2:
- PCI_SETBIT(pa->pa_pc, pa->pa_tag, BGE_PCI_DMA_RW_CTL,
+ PCI_SETBIT(sc->sc_pc, sc->sc_pcitag, BGE_PCI_DMA_RW_CTL,
BGE_PCI_WRITE_BNDRY_32BYTES);
break;
case 4:
- PCI_SETBIT(pa->pa_pc, pa->pa_tag, BGE_PCI_DMA_RW_CTL,
+ PCI_SETBIT(sc->sc_pc, sc->sc_pcitag, BGE_PCI_DMA_RW_CTL,
BGE_PCI_WRITE_BNDRY_64BYTES);
break;
case 8:
- PCI_SETBIT(pa->pa_pc, pa->pa_tag, BGE_PCI_DMA_RW_CTL,
+ PCI_SETBIT(sc->sc_pc, sc->sc_pcitag, BGE_PCI_DMA_RW_CTL,
BGE_PCI_WRITE_BNDRY_128BYTES);
break;
case 16:
- PCI_SETBIT(pa->pa_pc, pa->pa_tag, BGE_PCI_DMA_RW_CTL,
+ PCI_SETBIT(sc->sc_pc, sc->sc_pcitag, BGE_PCI_DMA_RW_CTL,
BGE_PCI_WRITE_BNDRY_256BYTES);
break;
case 32:
- PCI_SETBIT(pa->pa_pc, pa->pa_tag, BGE_PCI_DMA_RW_CTL,
+ PCI_SETBIT(sc->sc_pc, sc->sc_pcitag, BGE_PCI_DMA_RW_CTL,
BGE_PCI_WRITE_BNDRY_512BYTES);
break;
case 64:
- PCI_SETBIT(pa->pa_pc, pa->pa_tag, BGE_PCI_DMA_RW_CTL,
+ PCI_SETBIT(sc->sc_pc, sc->sc_pcitag, BGE_PCI_DMA_RW_CTL,
BGE_PCI_WRITE_BNDRY_1024BYTES);
break;
default:
@@ -1389,7 +1378,7 @@ bge_chipinit(struct bge_softc *sc)
"cache line size %d not supported "
"disabling PCI MWI\n",
#endif
- PCI_CLRBIT(pa->pa_pc, pa->pa_tag, BGE_PCI_CMD,
+ PCI_CLRBIT(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD,
PCIM_CMD_MWIEN);
break;
}
@@ -1399,7 +1388,7 @@ bge_chipinit(struct bge_softc *sc)
* Disable memory write invalidate. Apparently it is not supported
* properly by these devices.
*/
- PCI_CLRBIT(pa->pa_pc, pa->pa_tag, BGE_PCI_CMD, PCIM_CMD_MWIEN);
+ PCI_CLRBIT(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD, PCIM_CMD_MWIEN);
#ifdef __brokenalpha__
@@ -1434,8 +1423,7 @@ bge_blockinit(struct bge_softc *sc)
* ring RCBs, plus other things which live in NIC memory.
*/
- pci_conf_write(sc->bge_pa.pa_pc, sc->bge_pa.pa_tag,
- BGE_PCI_MEMWIN_BASEADDR, 0);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MEMWIN_BASEADDR, 0);
/* Configure mbuf memory pool */
if ((sc->bge_quirks & BGE_QUIRK_5705_CORE) == 0) {
@@ -2424,7 +2412,7 @@ bge_attach(device_t parent, device_t self, void *aux)
struct pci_attach_args *pa = aux;
const struct bge_product *bp;
const struct bge_revision *br;
- pci_chipset_tag_t pc = pa->pa_pc;
+ pci_chipset_tag_t pc = sc->sc_pc;
pci_intr_handle_t ih;
const char *intrstr = NULL;
bus_dma_segment_t seg;
@@ -2443,8 +2431,9 @@ bge_attach(device_t parent, device_t self, void *aux)
bp = bge_lookup(pa);
KASSERT(bp != NULL);
+ sc->sc_pc = pa->pa_pc;
+ sc->sc_pcitag = pa->pa_tag;
sc->bge_dev = self;
- sc->bge_pa = *pa;
aprint_naive(": Ethernet controller\n");
aprint_normal(": %s\n", bp->bp_name);
@@ -2453,10 +2442,10 @@ bge_attach(device_t parent, device_t self, void *aux)
* Map control/status registers.
*/
DPRINTFN(5, ("Map control/status regs\n"));
- command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
+ command = pci_conf_read(pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
command |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE;
- pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command);
- command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
+ pci_conf_write(pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, command);
+ command = pci_conf_read(pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
if (!(command & PCI_COMMAND_MEM_ENABLE)) {
aprint_error_dev(sc->bge_dev,
@@ -2465,7 +2454,7 @@ bge_attach(device_t parent, device_t self, void *aux)
}
DPRINTFN(5, ("pci_mem_find\n"));
- memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BGE_PCI_BAR0);
+ memtype = pci_mapreg_type(sc->sc_pc, sc->sc_pcitag, BGE_PCI_BAR0);
switch (memtype) {
case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
@@ -2505,10 +2494,10 @@ bge_attach(device_t parent, device_t self, void *aux)
* We do not have memory-mapped registers in this state,
* so force device into D0 state before starting initialization.
*/
- pm_ctl = pci_conf_read(pc, pa->pa_tag, BGE_PCI_PWRMGMT_CMD);
+ pm_ctl = pci_conf_read(pc, sc->sc_pcitag, BGE_PCI_PWRMGMT_CMD);
pm_ctl &= ~(PCI_PWR_D0|PCI_PWR_D1|PCI_PWR_D2|PCI_PWR_D3);
pm_ctl |= (1 << 8) | PCI_PWR_D0 ; /* D0 state */
- pci_conf_write(pc, pa->pa_tag, BGE_PCI_PWRMGMT_CMD, pm_ctl);
+ pci_conf_write(pc, sc->sc_pcitag, BGE_PCI_PWRMGMT_CMD, pm_ctl);
DELAY(1000); /* 27 usec is allegedly sufficent */
/*
@@ -2516,14 +2505,14 @@ bge_attach(device_t parent, device_t self, void *aux)
* ASIC.
*/
sc->bge_chipid =
- pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_MISC_CTL) &
+ pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL) &
BGE_PCIMISCCTL_ASICREV;
/*
* Detect PCI-Express devices
* XXX: guessed from Linux/FreeBSD; no documentation
*/
- if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIEXPRESS,
+ if (pci_get_capability(sc->sc_pc, sc->sc_pcitag, PCI_CAP_PCIEXPRESS,
NULL, NULL) != 0)
sc->bge_pcie = 1;
else
@@ -2651,6 +2640,7 @@ bge_attach(device_t parent, device_t self, void *aux)
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = bge_ioctl;
+ ifp->if_stop = bge_stop;
ifp->if_start = bge_start;
ifp->if_init = bge_init;
ifp->if_watchdog = bge_watchdog;
@@ -2698,7 +2688,7 @@ bge_attach(device_t parent, device_t self, void *aux)
sc->bge_tbi = 1;
/* The SysKonnect SK-9D41 is a 1000baseSX card. */
- if ((pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_SUBSYS) >> 16) ==
+ if ((pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_SUBSYS) >> 16) ==
SK_SUBSYSID_9D41)
sc->bge_tbi = 1;
@@ -2741,7 +2731,7 @@ bge_attach(device_t parent, device_t self, void *aux)
*/
if (sc->bge_quirks & BGE_QUIRK_PCIX_DMA_ALIGN_BUG) {
/* If in PCI-X mode, work around the alignment bug. */
- if ((pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_PCISTATE) &
+ if ((pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_PCISTATE) &
(BGE_PCISTATE_PCI_BUSMODE | BGE_PCISTATE_PCI_BUSSPEED)) ==
BGE_PCISTATE_PCI_BUSSPEED)
sc->bge_rx_alignment_bug = 1;
@@ -2776,11 +2766,10 @@ bge_attach(device_t parent, device_t self, void *aux)
DPRINTFN(5, ("callout_init\n"));
callout_init(&sc->bge_timeout, 0);
- sc->bge_powerhook = powerhook_establish(device_xname(sc->bge_dev),
- bge_powerhook, sc);
- if (sc->bge_powerhook == NULL)
- aprint_error_dev(sc->bge_dev,
- "unable to establish PCI power hook\n");
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, ifp);
}
static void
@@ -2796,16 +2785,15 @@ bge_release_resources(struct bge_softc *sc)
static void
bge_reset(struct bge_softc *sc)
{
- struct pci_attach_args *pa = &sc->bge_pa;
u_int32_t cachesize, command, pcistate, new_pcistate;
int i, val;
/* Save some important PCI state. */
- cachesize = pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_CACHESZ);
- command = pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_CMD);
- pcistate = pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_PCISTATE);
+ cachesize = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CACHESZ);
+ command = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD);
+ pcistate = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_PCISTATE);
- pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MISC_CTL,
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,
BGE_PCIMISCCTL_INDIRECT_ACCESS|BGE_PCIMISCCTL_MASK_PCI_INTR|
BGE_HIF_SWAP_OPTIONS|BGE_PCIMISCCTL_PCISTATE_RW);
@@ -2846,8 +2834,8 @@ bge_reset(struct bge_softc *sc)
DELAY(500000);
/* XXX: Magic Numbers */
- reg = pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_UNKNOWN0);
- pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_UNKNOWN0,
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_UNKNOWN0);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_UNKNOWN0,
reg | (1 << 15));
}
/*
@@ -2856,17 +2844,17 @@ bge_reset(struct bge_softc *sc)
* Should be replaced with references to PCI config-space
* capability block for PCI-Express.
*/
- pci_conf_write(pa->pa_pc, pa->pa_tag,
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag,
BGE_PCI_CONF_DEV_CTRL, 0xf5000);
}
/* Reset some of the PCI state that got zapped by reset */
- pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MISC_CTL,
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_MISC_CTL,
BGE_PCIMISCCTL_INDIRECT_ACCESS|BGE_PCIMISCCTL_MASK_PCI_INTR|
BGE_HIF_SWAP_OPTIONS|BGE_PCIMISCCTL_PCISTATE_RW);
- pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_CMD, command);
- pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_CACHESZ, cachesize);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CMD, command);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, BGE_PCI_CACHESZ, cachesize);
bge_writereg_ind(sc, BGE_MISC_CFG, (65 << 1));
/* Enable memory arbiter. */
@@ -2918,7 +2906,7 @@ bge_reset(struct bge_softc *sc)
* results.
*/
for (i = 0; i < 10000; i++) {
- new_pcistate = pci_conf_read(pa->pa_pc, pa->pa_tag,
+ new_pcistate = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
BGE_PCI_PCISTATE);
if ((new_pcistate & ~BGE_PCISTATE_RESERVED) ==
(pcistate & ~BGE_PCISTATE_RESERVED))
@@ -3943,7 +3931,7 @@ bge_init(struct ifnet *ifp)
ifp = &sc->ethercom.ec_if;
/* Cancel pending I/O and flush buffers. */
- bge_stop(sc);
+ bge_stop(ifp, 0);
bge_reset(sc);
bge_chipinit(sc);
@@ -4123,9 +4111,8 @@ bge_ioctl(struct ifnet *ifp, u_long command, void *data)
} else if (!(sc->bge_if_flags & IFF_UP))
bge_init(ifp);
} else {
- if (ifp->if_flags & IFF_RUNNING) {
- bge_stop(sc);
- }
+ if (ifp->if_flags & IFF_RUNNING)
+ bge_stop(ifp, 1);
}
sc->bge_if_flags = ifp->if_flags;
error = 0;
@@ -4215,9 +4202,9 @@ bge_stop_block(struct bge_softc *sc, bus_addr_t reg, uint32_t bit)
* RX and TX lists.
*/
static void
-bge_stop(struct bge_softc *sc)
+bge_stop(struct ifnet *ifp, int disable)
{
- struct ifnet *ifp = &sc->ethercom.ec_if;
+ struct bge_softc *sc = ifp->if_softc;
callout_stop(&sc->bge_timeout);
@@ -4296,20 +4283,6 @@ bge_stop(struct bge_softc *sc)
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
}
-/*
- * Stop all chip I/O so that the kernel's probe routines don't
- * get confused by errant DMAs when rebooting.
- */
-static void
-bge_shutdown(void *xsc)
-{
- struct bge_softc *sc = (struct bge_softc *)xsc;
-
- bge_stop(sc);
- bge_reset(sc);
-}
-
-
static int
sysctl_bge_verify(SYSCTLFN_ARGS)
{
@@ -4384,35 +4357,3 @@ SYSCTL_SETUP(sysctl_bge, "sysctl bge subtree setup")
err:
aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
}
-
-static void
-bge_powerhook(int why, void *hdl)
-{
- struct bge_softc *sc = (struct bge_softc *)hdl;
- struct ifnet *ifp = &sc->ethercom.ec_if;
- struct pci_attach_args *pa = &(sc->bge_pa);
- pci_chipset_tag_t pc = pa->pa_pc;
- pcitag_t tag = pa->pa_tag;
-
- switch (why) {
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- bge_shutdown(sc);
- break;
- case PWR_SOFTRESUME:
- if (ifp->if_flags & IFF_UP) {
- ifp->if_flags &= ~IFF_RUNNING;
- bge_init(ifp);
- }
- break;
- case PWR_SUSPEND:
- case PWR_STANDBY:
- pci_conf_capture(pc, tag, &sc->bge_pciconf);
- break;
- case PWR_RESUME:
- pci_conf_restore(pc, tag, &sc->bge_pciconf);
- break;
- }
-
- return;
-}
diff --git a/sys/dev/pci/if_bgereg.h b/sys/dev/pci/if_bgereg.h
index a643ca3bb8a..edc459bcbc1 100644
--- a/sys/dev/pci/if_bgereg.h
+++ b/sys/dev/pci/if_bgereg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bgereg.h,v 1.44 2007/09/24 21:25:45 joerg Exp $ */
+/* $NetBSD: if_bgereg.h,v 1.45 2007/12/09 20:28:08 jmcneill Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
* Copyright (c) 1997, 1998, 1999, 2001
@@ -2385,7 +2385,9 @@ struct bge_softc {
bus_space_handle_t bge_bhandle;
bus_space_tag_t bge_btag;
void *bge_intrhand;
- struct pci_attach_args bge_pa;
+ pci_chipset_tag_t sc_pc;
+ pcitag_t sc_pcitag;
+
struct mii_data bge_mii;
struct ifmedia bge_ifmedia; /* media info */
u_int8_t bge_extram; /* has external SSRAM */
@@ -2437,6 +2439,4 @@ struct bge_softc {
int bge_pending_rxintr_change;
SLIST_HEAD(, txdmamap_pool_entry) txdma_list;
struct txdmamap_pool_entry *txdma[BGE_TX_RING_CNT];
- void *bge_powerhook;
- struct pci_conf_state bge_pciconf;
};
diff --git a/sys/dev/pci/if_ipw.c b/sys/dev/pci/if_ipw.c
index 9c28578fe4b..5595a48fabc 100644
--- a/sys/dev/pci/if_ipw.c
+++ b/sys/dev/pci/if_ipw.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ipw.c,v 1.34 2007/10/19 12:00:45 ad Exp $ */
+/* $NetBSD: if_ipw.c,v 1.35 2007/12/09 20:28:09 jmcneill Exp $ */
/* FreeBSD: src/sys/dev/ipw/if_ipw.c,v 1.15 2005/11/13 17:17:40 damien Exp */
/*-
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ipw.c,v 1.34 2007/10/19 12:00:45 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ipw.c,v 1.35 2007/12/09 20:28:09 jmcneill Exp $");
/*-
* Intel(R) PRO/Wireless 2100 MiniPCI driver
@@ -94,10 +94,7 @@ static int ipw_match(struct device *, struct cfdata *, void *);
static void ipw_attach(struct device *, struct device *, void *);
static int ipw_detach(struct device *, int);
-static void ipw_shutdown(void *);
-static int ipw_suspend(struct ipw_softc *);
-static int ipw_resume(struct ipw_softc *);
-static void ipw_powerhook(int, void *);
+static bool ipw_resume(device_t);
static int ipw_media_change(struct ifnet *);
static void ipw_media_status(struct ifnet *, struct ifmediareq *);
@@ -204,10 +201,7 @@ ipw_attach(struct device *parent, struct device *self, void *aux)
data |= PCI_COMMAND_MASTER_ENABLE;
pci_conf_write(sc->sc_pct, pa->pa_tag, PCI_COMMAND_STATUS_REG, data);
- /* clear device specific PCI configuration register 0x41 */
- data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
- data &= ~0x0000ff00;
- pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
+ pci_disable_retry(sc->sc_pct, sc->sc_pcitag);
/* map the register window */
error = pci_mapreg_map(pa, IPW_PCI_BAR0, PCI_MAPREG_TYPE_MEM |
@@ -340,18 +334,10 @@ ipw_attach(struct device *parent, struct device *self, void *aux)
*/
sc->dwelltime = 100;
- /*
- * Make sure the interface is shutdown during reboot.
- */
- sc->sc_sdhook = shutdownhook_establish(ipw_shutdown, sc);
- if (sc->sc_sdhook == NULL)
- aprint_error("%s: WARNING: unable to establish shutdown hook\n",
- sc->sc_dev.dv_xname);
- sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- ipw_powerhook, sc);
- if (sc->sc_powerhook == NULL)
- printf("%s: WARNING: unable to establish power hook\n",
- sc->sc_dev.dv_xname);
+ if (!pmf_device_register(self, NULL, ipw_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, ifp);
ieee80211_announce(ic);
@@ -756,67 +742,14 @@ ipw_release(struct ipw_softc *sc)
}
-static void
-ipw_shutdown(void *arg)
+static bool
+ipw_resume(device_t dv)
{
- struct ipw_softc *sc = (struct ipw_softc *)arg;
- struct ifnet *ifp = sc->sc_ic.ic_ifp;
+ struct ipw_softc *sc = device_private(dv);
- ipw_stop(ifp, 1);
-}
+ pci_disable_retry(sc->sc_pct, sc->sc_pcitag);
-
-static int
-ipw_suspend(struct ipw_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ic.ic_ifp;
-
- ipw_stop(ifp, 1);
-
- return 0;
-}
-
-static int
-ipw_resume(struct ipw_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ic.ic_ifp;
- pcireg_t data;
-
- /* clear device specific PCI configuration register 0x41 */
- data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
- data &= ~0x0000ff00;
- pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
-
- if (ifp->if_flags & IFF_UP) {
- ipw_init(ifp);
- if (ifp->if_flags & IFF_RUNNING)
- ipw_start(ifp);
- }
-
- return 0;
-}
-
-static void
-ipw_powerhook(int why, void *arg)
-{
- struct ipw_softc *sc = arg;
- int s;
-
- s = splnet();
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- ipw_suspend(sc);
- break;
- case PWR_RESUME:
- ipw_resume(sc);
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
- }
- splx(s);
+ return true;
}
static int
diff --git a/sys/dev/pci/if_ipwvar.h b/sys/dev/pci/if_ipwvar.h
index 53afc561a4c..a71c4a07c85 100644
--- a/sys/dev/pci/if_ipwvar.h
+++ b/sys/dev/pci/if_ipwvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ipwvar.h,v 1.11 2006/04/17 20:57:24 rpaulo Exp $ */
+/* $NetBSD: if_ipwvar.h,v 1.12 2007/12/09 20:28:09 jmcneill Exp $ */
/*-
* Copyright (c) 2004
@@ -109,9 +109,6 @@ struct ipw_softc {
pcitag_t sc_pcitag;
bus_size_t sc_sz;
- void *sc_sdhook; /* shutdown hook */
- void *sc_powerhook; /* power management hook */
-
int sc_tx_timer;
bus_dma_tag_t sc_dmat;
diff --git a/sys/dev/pci/if_iwi.c b/sys/dev/pci/if_iwi.c
index 9c7365af277..906360e800b 100644
--- a/sys/dev/pci/if_iwi.c
+++ b/sys/dev/pci/if_iwi.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_iwi.c,v 1.67 2007/10/22 15:31:46 joerg Exp $ */
+/* $NetBSD: if_iwi.c,v 1.68 2007/12/09 20:28:09 jmcneill Exp $ */
/*-
* Copyright (c) 2004, 2005
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_iwi.c,v 1.67 2007/10/22 15:31:46 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_iwi.c,v 1.68 2007/12/09 20:28:09 jmcneill Exp $");
/*-
* Intel(R) PRO/Wireless 2200BG/2225BG/2915ABG driver
@@ -94,11 +94,6 @@ static int iwi_match(device_t, struct cfdata *, void *);
static void iwi_attach(device_t, device_t, void *);
static int iwi_detach(device_t, int);
-static void iwi_shutdown(void *);
-static int iwi_suspend(struct iwi_softc *);
-static int iwi_resume(struct iwi_softc *);
-static void iwi_powerhook(int, void *);
-
static int iwi_alloc_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *,
int);
static void iwi_reset_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *);
@@ -206,6 +201,16 @@ iwi_match(device_t parent, struct cfdata *match, void *aux)
return 0;
}
+static bool
+iwi_pci_resume(device_t dv)
+{
+ struct iwi_softc *sc = device_private(dv);
+
+ pci_disable_retry(sc->sc_pct, sc->sc_pcitag);
+
+ return true;
+}
+
/* Base Address Register */
#define IWI_PCI_BAR0 0x10
@@ -233,10 +238,7 @@ iwi_attach(device_t parent, device_t self, void *aux)
revision = PCI_REVISION(pa->pa_class);
aprint_normal(": %s (rev. 0x%02x)\n", devinfo, revision);
- /* clear device specific PCI configuration register 0x41 */
- data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
- data &= ~0x0000ff00;
- pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
+ pci_disable_retry(sc->sc_pct, sc->sc_pcitag);
/* clear unit numbers allocated to IBSS */
sc->sc_unr = 0;
@@ -435,18 +437,10 @@ iwi_attach(device_t parent, device_t self, void *aux)
iwi_sysctlattach(sc);
- /*
- * Make sure the interface is shutdown during reboot.
- */
- sc->sc_sdhook = shutdownhook_establish(iwi_shutdown, sc);
- if (sc->sc_sdhook == NULL)
- aprint_error_dev(self,
- "WARNING: unable to establish shutdown hook\n");
- sc->sc_powerhook = powerhook_establish(device_xname(self),
- iwi_powerhook, sc);
- if (sc->sc_powerhook == NULL)
- aprint_error_dev(self,
- "WARNING: unable to establish power hook\n");
+ if (!pmf_device_register(self, NULL, iwi_pci_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, ifp);
ieee80211_announce(ic);
@@ -461,6 +455,8 @@ iwi_detach(device_t self, int flags)
struct iwi_softc *sc = device_private(self);
struct ifnet *ifp = &sc->sc_if;
+ pmf_device_deregister(self);
+
if (ifp != NULL)
iwi_stop(ifp, 1);
@@ -484,9 +480,6 @@ iwi_detach(device_t self, int flags)
bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz);
- powerhook_disestablish(sc->sc_powerhook);
- shutdownhook_disestablish(sc->sc_sdhook);
-
return 0;
}
@@ -784,73 +777,6 @@ iwi_free_rx_ring(struct iwi_softc *sc, struct iwi_rx_ring *ring)
}
}
-static void
-iwi_shutdown(void *arg)
-{
- struct iwi_softc *sc = (struct iwi_softc *)arg;
- struct ifnet *ifp = sc->sc_ic.ic_ifp;
-
- iwi_stop(ifp, 1);
-}
-
-static int
-iwi_suspend(struct iwi_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ic.ic_ifp;
-
- iwi_stop(ifp, 1);
-
- return 0;
-}
-
-static int
-iwi_resume(struct iwi_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ic.ic_ifp;
- pcireg_t data;
-
- /* clear device specific PCI configuration register 0x41 */
- data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
- data &= ~0x0000ff00;
- pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
-
- if (ifp->if_flags & IFF_UP) {
- iwi_init(ifp);
- if (ifp->if_flags & IFF_RUNNING)
- iwi_start(ifp);
- }
-
- return 0;
-}
-
-static void
-iwi_powerhook(int why, void *arg)
-{
- struct iwi_softc *sc = arg;
- pci_chipset_tag_t pc = sc->sc_pct;
- pcitag_t tag = sc->sc_pcitag;
- int s;
-
- s = splnet();
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- pci_conf_capture(pc, tag, &sc->sc_pciconf);
- break;
- case PWR_RESUME:
- pci_conf_restore(pc, tag, &sc->sc_pciconf);
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- iwi_suspend(sc);
- break;
- case PWR_SOFTRESUME:
- iwi_resume(sc);
- break;
- }
- splx(s);
-}
-
static struct ieee80211_node *
iwi_node_alloc(struct ieee80211_node_table *nt)
{
diff --git a/sys/dev/pci/if_iwivar.h b/sys/dev/pci/if_iwivar.h
index 0ada21412d8..ea55920d05d 100644
--- a/sys/dev/pci/if_iwivar.h
+++ b/sys/dev/pci/if_iwivar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_iwivar.h,v 1.14 2007/10/22 15:28:48 joerg Exp $ */
+/* $NetBSD: if_iwivar.h,v 1.15 2007/12/09 20:28:09 jmcneill Exp $ */
/*-
* Copyright (c) 2004, 2005
@@ -144,10 +144,6 @@ struct iwi_softc {
pcitag_t sc_pcitag;
bus_size_t sc_sz;
- void *sc_sdhook; /* shutdown hook */
- void *sc_powerhook; /* power management hook */
- struct pci_conf_state sc_pciconf;
-
struct sysctllog *sc_sysctllog;
int antenna;
diff --git a/sys/dev/pci/if_nfe.c b/sys/dev/pci/if_nfe.c
index 8a003b97c6f..f58201e3e5d 100644
--- a/sys/dev/pci/if_nfe.c
+++ b/sys/dev/pci/if_nfe.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_nfe.c,v 1.23 2007/11/14 14:59:50 xtraeme Exp $ */
+/* $NetBSD: if_nfe.c,v 1.24 2007/12/09 20:28:09 jmcneill Exp $ */
/* $OpenBSD: if_nfe.c,v 1.52 2006/03/02 09:04:00 jsg Exp $ */
/*-
@@ -21,7 +21,7 @@
/* Driver for NVIDIA nForce MCP Fast Ethernet and Gigabit Ethernet */
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_nfe.c,v 1.23 2007/11/14 14:59:50 xtraeme Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_nfe.c,v 1.24 2007/12/09 20:28:09 jmcneill Exp $");
#include "opt_inet.h"
#include "bpfilter.h"
@@ -323,6 +323,7 @@ nfe_attach(struct device *parent, struct device *self, void *aux)
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = nfe_ioctl;
ifp->if_start = nfe_start;
+ ifp->if_stop = nfe_stop;
ifp->if_watchdog = nfe_watchdog;
ifp->if_init = nfe_init;
ifp->if_baudrate = IF_Gbps(1);
@@ -365,25 +366,10 @@ nfe_attach(struct device *parent, struct device *self, void *aux)
callout_init(&sc->sc_tick_ch, 0);
callout_setfunc(&sc->sc_tick_ch, nfe_tick, sc);
- sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- nfe_power, sc);
-}
-
-void
-nfe_power(int why, void *arg)
-{
- struct nfe_softc *sc = arg;
- struct ifnet *ifp;
-
- if (why == PWR_RESUME) {
- ifp = &sc->sc_ethercom.ec_if;
- if (ifp->if_flags & IFF_UP) {
- ifp->if_flags &= ~IFF_RUNNING;
- nfe_init(ifp);
- if (ifp->if_flags & IFF_RUNNING)
- nfe_start(ifp);
- }
- }
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, ifp);
}
void
diff --git a/sys/dev/pci/if_nfevar.h b/sys/dev/pci/if_nfevar.h
index 368cedf5964..f4c2137e03b 100644
--- a/sys/dev/pci/if_nfevar.h
+++ b/sys/dev/pci/if_nfevar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_nfevar.h,v 1.3 2007/09/24 13:17:54 cube Exp $ */
+/* $NetBSD: if_nfevar.h,v 1.4 2007/12/09 20:28:09 jmcneill Exp $ */
/* $OpenBSD: if_nfevar.h,v 1.11 2006/02/19 13:57:02 damien Exp $ */
/*-
@@ -76,7 +76,6 @@ struct nfe_softc {
bus_dma_tag_t sc_dmat;
struct mii_data sc_mii;
struct callout sc_tick_ch;
- void *sc_powerhook;
int sc_if_flags;
u_int sc_flags;
diff --git a/sys/dev/pci/if_re_pci.c b/sys/dev/pci/if_re_pci.c
index 3d1c610432b..10100ab8d83 100644
--- a/sys/dev/pci/if_re_pci.c
+++ b/sys/dev/pci/if_re_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_re_pci.c,v 1.30 2007/10/19 12:00:47 ad Exp $ */
+/* $NetBSD: if_re_pci.c,v 1.31 2007/12/09 20:28:09 jmcneill Exp $ */
/*
* Copyright (c) 1997, 1998-2003
@@ -183,43 +183,13 @@ re_pci_attach(struct device *parent, struct device *self, void *aux)
const struct rtk_type *t;
uint32_t hwrev;
int error = 0;
- pcireg_t pmreg, memtype;
+ pcireg_t memtype;
bool ioh_valid, memh_valid;
pcireg_t command;
bus_space_tag_t iot, memt;
bus_space_handle_t ioh, memh;
bus_size_t iosize, memsize, bsize;
-
- /*
- * Handle power management nonsense.
- */
- if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) {
- command = pci_conf_read(pc, pa->pa_tag, pmreg + PCI_PMCSR);
- if (command & PCI_PMCSR_STATE_MASK) {
- u_int32_t iobase, membase, irq;
-
- /* Save important PCI config data. */
- iobase = pci_conf_read(pc, pa->pa_tag, RTK_PCI_LOIO);
- membase = pci_conf_read(pc, pa->pa_tag, RTK_PCI_LOMEM);
- irq = pci_conf_read(pc, pa->pa_tag, PCI_INTERRUPT_REG);
-
- /* Reset the power state. */
- aprint_normal("%s: chip is is in D%d power mode "
- "-- setting to D0\n", sc->sc_dev.dv_xname,
- command & PCI_PMCSR_STATE_MASK);
-
- command &= ~PCI_PMCSR_STATE_MASK;
- pci_conf_write(pc, pa->pa_tag,
- pmreg + PCI_PMCSR, command);
-
- /* Restore PCI config data. */
- pci_conf_write(pc, pa->pa_tag, RTK_PCI_LOIO, iobase);
- pci_conf_write(pc, pa->pa_tag, RTK_PCI_LOMEM, membase);
- pci_conf_write(pc, pa->pa_tag, PCI_INTERRUPT_REG, irq);
- }
- }
-
/*
* Map control/status registers.
*/
@@ -329,4 +299,9 @@ re_pci_attach(struct device *parent, struct device *self, void *aux)
bus_space_unmap(memt, memh, memsize);
}
}
+
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, &sc->ethercom.ec_if);
}
diff --git a/sys/dev/pci/if_rtk_pci.c b/sys/dev/pci/if_rtk_pci.c
index c9422141883..de7fa68de56 100644
--- a/sys/dev/pci/if_rtk_pci.c
+++ b/sys/dev/pci/if_rtk_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_rtk_pci.c,v 1.34 2007/11/06 02:29:19 uwe Exp $ */
+/* $NetBSD: if_rtk_pci.c,v 1.35 2007/12/09 20:28:10 jmcneill Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -47,7 +47,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_rtk_pci.c,v 1.34 2007/11/06 02:29:19 uwe Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_rtk_pci.c,v 1.35 2007/12/09 20:28:10 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -82,11 +82,6 @@ struct rtk_pci_softc {
/* PCI-specific goo.*/
void *sc_ih;
- pci_chipset_tag_t sc_pc; /* PCI chipset */
- pcitag_t sc_pcitag; /* PCI tag */
-
- void *sc_powerhook; /* powerhook ctxt. */
- struct pci_conf_state sc_pciconf;
};
static const struct rtk_type rtk_pci_devs[] = {
@@ -111,7 +106,6 @@ static const struct rtk_type rtk_pci_devs[] = {
static int rtk_pci_match(device_t, struct cfdata *, void *);
static void rtk_pci_attach(device_t, device_t, void *);
-static void rtk_pci_powerhook(int, void *);
CFATTACH_DECL(rtk_pci, sizeof(struct rtk_pci_softc),
rtk_pci_match, rtk_pci_attach, NULL, NULL);
@@ -151,7 +145,6 @@ rtk_pci_attach(device_t parent, device_t self, void *aux)
{
struct rtk_pci_softc *psc = device_private(self);
struct rtk_softc *sc = &psc->sc_rtk;
- pcireg_t command;
struct pci_attach_args *pa = aux;
pci_chipset_tag_t pc = pa->pa_pc;
pci_intr_handle_t ih;
@@ -159,12 +152,8 @@ rtk_pci_attach(device_t parent, device_t self, void *aux)
bus_space_handle_t ioh, memh;
const char *intrstr = NULL;
const struct rtk_type *t;
- int pmreg;
int ioh_valid, memh_valid;
- psc->sc_pc = pa->pa_pc;
- psc->sc_pcitag = pa->pa_tag;
-
t = rtk_pci_lookup(pa);
if (t == NULL) {
printf("\n");
@@ -176,35 +165,6 @@ rtk_pci_attach(device_t parent, device_t self, void *aux)
t->rtk_name, PCI_REVISION(pa->pa_class));
/*
- * Handle power management nonsense.
- */
-
- if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) {
- command = pci_conf_read(pc, pa->pa_tag, pmreg + PCI_PMCSR);
- if (command & PCI_PMCSR_STATE_MASK) {
- pcireg_t iobase, membase, irq;
-
- /* Save important PCI config data. */
- iobase = pci_conf_read(pc, pa->pa_tag, RTK_PCI_LOIO);
- membase = pci_conf_read(pc, pa->pa_tag, RTK_PCI_LOMEM);
- irq = pci_conf_read(pc, pa->pa_tag, PCI_INTERRUPT_REG);
-
- /* Reset the power state. */
- aprint_normal_dev(self,
- "chip is in D%d power mode -- setting to D0\n",
- command & PCI_PMCSR_STATE_MASK);
- command &= ~PCI_PMCSR_STATE_MASK;
- pci_conf_write(pc, pa->pa_tag,
- pmreg + PCI_PMCSR, command);
-
- /* Restore PCI config data. */
- pci_conf_write(pc, pa->pa_tag, RTK_PCI_LOIO, iobase);
- pci_conf_write(pc, pa->pa_tag, RTK_PCI_LOMEM, membase);
- pci_conf_write(pc, pa->pa_tag, PCI_INTERRUPT_REG, irq);
- }
- }
-
- /*
* Map control/status registers.
*
* The original FreeBSD's driver has the following comment:
@@ -258,34 +218,10 @@ rtk_pci_attach(device_t parent, device_t self, void *aux)
sc->sc_dmat = pa->pa_dmat;
sc->sc_flags |= RTK_ENABLED;
- psc->sc_powerhook = powerhook_establish(device_xname(self),
- rtk_pci_powerhook, psc);
- if (psc->sc_powerhook == NULL)
- aprint_error_dev(self,
- "WARNING: unable to establish pci power hook\n");
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, &sc->ethercom.ec_if);
rtk_attach(sc);
}
-
-static void
-rtk_pci_powerhook(int why, void *arg)
-{
- struct rtk_pci_softc *sc = (struct rtk_pci_softc *)arg;
- int s;
-
- s = splnet();
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- pci_conf_capture(sc->sc_pc, sc->sc_pcitag, &sc->sc_pciconf);
- break;
- case PWR_RESUME:
- pci_conf_restore(sc->sc_pc, sc->sc_pcitag, &sc->sc_pciconf);
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
- }
- splx(s);
-}
diff --git a/sys/dev/pci/if_wi_pci.c b/sys/dev/pci/if_wi_pci.c
index d113cda1900..78e7db292ae 100644
--- a/sys/dev/pci/if_wi_pci.c
+++ b/sys/dev/pci/if_wi_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wi_pci.c,v 1.42 2007/10/19 12:00:49 ad Exp $ */
+/* $NetBSD: if_wi_pci.c,v 1.43 2007/12/09 20:28:10 jmcneill Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wi_pci.c,v 1.42 2007/10/19 12:00:49 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wi_pci.c,v 1.43 2007/12/09 20:28:10 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -92,8 +92,7 @@ struct wi_pci_softc {
/* PCI-specific goo */
pci_intr_handle_t psc_ih;
pci_chipset_tag_t psc_pc;
-
- void *sc_powerhook; /* power hook descriptor */
+ pcitag_t psc_pcitag;
};
static int wi_pci_match(struct device *, struct cfdata *, void *);
@@ -101,7 +100,6 @@ static void wi_pci_attach(struct device *, struct device *, void *);
static int wi_pci_enable(struct wi_softc *);
static void wi_pci_disable(struct wi_softc *);
static void wi_pci_reset(struct wi_softc *);
-static void wi_pci_powerhook(int, void *);
static const struct wi_pci_product
*wi_pci_lookup(struct pci_attach_args *);
@@ -236,6 +234,7 @@ wi_pci_attach(struct device *parent, struct device *self, void *aux)
bus_space_handle_t memh, ioh, plxh, tmdh;
psc->psc_pc = pc;
+ psc->psc_pcitag = pa->pa_tag;
wpp = wi_pci_lookup(pa);
#ifdef DIAGNOSTIC
@@ -383,19 +382,8 @@ wi_pci_attach(struct device *parent, struct device *self, void *aux)
if (!wpp->wpp_chip)
sc->sc_reset = wi_pci_reset;
- /* Add a suspend hook to restore PCI config state */
- psc->sc_powerhook = powerhook_establish(self->dv_xname,
- wi_pci_powerhook, psc);
- if (psc->sc_powerhook == NULL)
- printf("%s: WARNING: unable to establish pci power hook\n",
- self->dv_xname);
-}
-
-static void
-wi_pci_powerhook(int why, void *arg)
-{
- struct wi_pci_softc *psc = arg;
- struct wi_softc *sc = &psc->psc_wi;
-
- wi_power(sc, why);
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, &sc->sc_if);
}
diff --git a/sys/dev/pci/if_wm.c b/sys/dev/pci/if_wm.c
index 40722b613f2..9819385cf28 100644
--- a/sys/dev/pci/if_wm.c
+++ b/sys/dev/pci/if_wm.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.148 2007/10/30 07:49:40 simonb Exp $ */
+/* $NetBSD: if_wm.c,v 1.149 2007/12/09 20:28:10 jmcneill Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -79,7 +79,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.148 2007/10/30 07:49:40 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.149 2007/12/09 20:28:10 jmcneill Exp $");
#include "bpfilter.h"
#include "rnd.h"
@@ -268,11 +268,8 @@ struct wm_softc {
bus_space_handle_t sc_flashh; /* flash registers space handle */
bus_dma_tag_t sc_dmat; /* bus DMA tag */
struct ethercom sc_ethercom; /* ethernet common data */
- void *sc_sdhook; /* shutdown hook */
- void *sc_powerhook; /* power hook */
pci_chipset_tag_t sc_pc;
pcitag_t sc_pcitag;
- struct pci_conf_state sc_pciconf;
wm_chip_type sc_type; /* chip type */
int sc_flags; /* flags; see below */
@@ -523,9 +520,6 @@ static int wm_ioctl(struct ifnet *, u_long, void *);
static int wm_init(struct ifnet *);
static void wm_stop(struct ifnet *, int);
-static void wm_shutdown(void *);
-static void wm_powerhook(int, void *);
-
static void wm_reset(struct wm_softc *);
static void wm_rxdrain(struct wm_softc *);
static int wm_add_rxbuf(struct wm_softc *, int);
@@ -1617,19 +1611,11 @@ wm_attach(struct device *parent, struct device *self, void *aux)
NULL, sc->sc_dev.dv_xname, "rx_macctl");
#endif /* WM_EVENT_COUNTERS */
- /*
- * Make sure the interface is shutdown during reboot.
- */
- sc->sc_sdhook = shutdownhook_establish(wm_shutdown, sc);
- if (sc->sc_sdhook == NULL)
- aprint_error("%s: WARNING: unable to establish shutdown hook\n",
- sc->sc_dev.dv_xname);
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, ifp);
- sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- wm_powerhook, sc);
- if (sc->sc_powerhook == NULL)
- aprint_error("%s: can't establish powerhook\n",
- sc->sc_dev.dv_xname);
return;
/*
@@ -1661,48 +1647,6 @@ wm_attach(struct device *parent, struct device *self, void *aux)
}
/*
- * wm_shutdown:
- *
- * Make sure the interface is stopped at reboot time.
- */
-static void
-wm_shutdown(void *arg)
-{
- struct wm_softc *sc = arg;
-
- wm_stop(&sc->sc_ethercom.ec_if, 1);
-}
-
-static void
-wm_powerhook(int why, void *arg)
-{
- struct wm_softc *sc = arg;
- struct ifnet *ifp = &sc->sc_ethercom.ec_if;
- pci_chipset_tag_t pc = sc->sc_pc;
- pcitag_t tag = sc->sc_pcitag;
-
- switch (why) {
- case PWR_SOFTSUSPEND:
- wm_shutdown(sc);
- break;
- case PWR_SOFTRESUME:
- ifp->if_flags &= ~IFF_RUNNING;
- wm_init(ifp);
- if (ifp->if_flags & IFF_RUNNING)
- wm_start(ifp);
- break;
- case PWR_SUSPEND:
- pci_conf_capture(pc, tag, &sc->sc_pciconf);
- break;
- case PWR_RESUME:
- pci_conf_restore(pc, tag, &sc->sc_pciconf);
- break;
- }
-
- return;
-}
-
-/*
* wm_tx_offload:
*
* Set up TCP/IP checksumming parameters for the
diff --git a/sys/dev/pci/if_wpi.c b/sys/dev/pci/if_wpi.c
index 7b945dcdd09..f92a32791b8 100644
--- a/sys/dev/pci/if_wpi.c
+++ b/sys/dev/pci/if_wpi.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wpi.c,v 1.32 2007/12/01 18:02:42 jmcneill Exp $ */
+/* $NetBSD: if_wpi.c,v 1.33 2007/12/09 20:28:10 jmcneill Exp $ */
/*-
* Copyright (c) 2006, 2007
@@ -18,7 +18,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wpi.c,v 1.32 2007/12/01 18:02:42 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wpi.c,v 1.33 2007/12/09 20:28:10 jmcneill Exp $");
/*
* Driver for Intel PRO/Wireless 3945ABG 802.11 network adapters.
@@ -94,7 +94,6 @@ static const struct ieee80211_rateset wpi_rateset_11g =
static int wpi_match(device_t, struct cfdata *, void *);
static void wpi_attach(device_t, device_t, void *);
static int wpi_detach(device_t , int);
-static void wpi_power(int, void *);
static int wpi_dma_contig_alloc(bus_dma_tag_t, struct wpi_dma_info *,
void **, bus_size_t, bus_size_t, int);
static void wpi_dma_contig_free(struct wpi_dma_info *);
@@ -164,6 +163,7 @@ static int wpi_reset(struct wpi_softc *);
static void wpi_hw_config(struct wpi_softc *);
static int wpi_init(struct ifnet *);
static void wpi_stop(struct ifnet *, int);
+static bool wpi_resume(device_t);
CFATTACH_DECL_NEW(wpi, sizeof (struct wpi_softc), wpi_match, wpi_attach,
wpi_detach, NULL);
@@ -212,10 +212,7 @@ wpi_attach(device_t parent __unused, device_t self, void *aux)
revision = PCI_REVISION(pa->pa_class);
aprint_normal(": %s (rev. 0x%02x)\n", devinfo, revision);
- /* clear device specific PCI configuration register 0x41 */
- data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
- data &= ~0x0000ff00;
- pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
+ pci_disable_retry(pa->pa_pc, pa->pa_tag);
/* enable bus-mastering */
data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
@@ -343,8 +340,10 @@ wpi_attach(device_t parent __unused, device_t self, void *aux)
sc->amrr.amrr_min_success_threshold = 1;
sc->amrr.amrr_max_success_threshold = 15;
- /* set powerhook */
- sc->powerhook = powerhook_establish(device_xname(self), wpi_power, sc);
+ if (!pmf_device_register(self, NULL, wpi_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, ifp);
#if NBPFILTER > 0
bpfattach2(ifp, DLT_IEEE802_11_RADIO,
@@ -406,32 +405,6 @@ wpi_detach(device_t self, int flags __unused)
return 0;
}
-static void
-wpi_power(int why, void *arg)
-{
- struct wpi_softc *sc = arg;
- struct ifnet *ifp;
- pcireg_t data;
- int s;
-
- if (why != PWR_RESUME)
- return;
-
- /* clear device specific PCI configuration register 0x41 */
- data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
- data &= ~0x0000ff00;
- pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
-
- s = splnet();
- ifp = sc->sc_ic.ic_ifp;
- if (ifp->if_flags & IFF_UP) {
- ifp->if_init(ifp);
- if (ifp->if_flags & IFF_RUNNING)
- ifp->if_start(ifp);
- }
- splx(s);
-}
-
static int
wpi_dma_contig_alloc(bus_dma_tag_t tag, struct wpi_dma_info *dma,
void **kvap, bus_size_t size, bus_size_t alignment, int flags)
@@ -3153,3 +3126,14 @@ wpi_stop(struct ifnet *ifp, int disable)
tmp = WPI_READ(sc, WPI_RESET);
WPI_WRITE(sc, WPI_RESET, tmp | WPI_SW_RESET);
}
+
+static bool
+wpi_resume(device_t dv)
+{
+ struct wpi_softc *sc = device_private(dv);
+
+ pci_disable_retry(sc->sc_pct, sc->sc_pcitag);
+ (void)wpi_reset(sc);
+
+ return true;
+}
diff --git a/sys/dev/pci/if_wpivar.h b/sys/dev/pci/if_wpivar.h
index 84657505c9f..b8e34fdff79 100644
--- a/sys/dev/pci/if_wpivar.h
+++ b/sys/dev/pci/if_wpivar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wpivar.h,v 1.9 2007/11/16 00:13:32 degroote Exp $ */
+/* $NetBSD: if_wpivar.h,v 1.10 2007/12/09 20:28:11 jmcneill Exp $ */
/*-
* Copyright (c) 2006
@@ -166,7 +166,6 @@ struct wpi_softc {
int8_t maxpwr[IEEE80211_CHAN_MAX];
int sc_tx_timer;
- void *powerhook;
#if NBPFILTER > 0
void * sc_drvbpf;
diff --git a/sys/dev/pci/neo.c b/sys/dev/pci/neo.c
index 7b02a93e142..c4b2a84ecc8 100644
--- a/sys/dev/pci/neo.c
+++ b/sys/dev/pci/neo.c
@@ -1,4 +1,4 @@
-/* $NetBSD: neo.c,v 1.36 2007/10/19 12:00:52 ad Exp $ */
+/* $NetBSD: neo.c,v 1.37 2007/12/09 20:28:11 jmcneill Exp $ */
/*
* Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: neo.c,v 1.36 2007/10/19 12:00:52 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: neo.c,v 1.37 2007/12/09 20:28:11 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -162,8 +162,6 @@ struct neo_softc {
struct ac97_codec_if *codec_if;
struct ac97_host_if host_if;
-
- void *powerhook;
};
/* -------------------------------------------------------------------- */
@@ -207,7 +205,6 @@ static void neo_free(void *, void *, struct malloc_type *);
static size_t neo_round_buffersize(void *, int, size_t);
static paddr_t neo_mappage(void *, void *, off_t, int);
static int neo_get_props(void *);
-static void neo_power(int, void *);
CFATTACH_DECL(neo, sizeof(struct neo_softc),
neo_match, neo_attach, NULL, NULL);
@@ -552,16 +549,15 @@ neo_match(struct device *parent, struct cfdata *match,
return 0;
}
-static void
-neo_power(int why, void *addr)
+static bool
+neo_resume(device_t dv)
{
- struct neo_softc *sc;
+ struct neo_softc *sc = device_private(dv);
- sc = (struct neo_softc *)addr;
- if (why == PWR_RESUME) {
- nm_init(sc);
- sc->codec_if->vtbl->restore_ports(sc->codec_if);
- }
+ nm_init(sc);
+ sc->codec_if->vtbl->restore_ports(sc->codec_if);
+
+ return true;
}
static void
@@ -634,7 +630,8 @@ neo_attach(struct device *parent, struct device *self, void *aux)
if (ac97_attach(&sc->host_if, self) != 0)
return;
- sc->powerhook = powerhook_establish(sc->dev.dv_xname, neo_power, sc);
+ if (!pmf_device_register(self, NULL, neo_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
audio_attach_mi(&neo_hw_if, sc, &sc->dev);
}
diff --git a/sys/dev/pci/ohci_pci.c b/sys/dev/pci/ohci_pci.c
index e96804ae48d..2468a6daa55 100644
--- a/sys/dev/pci/ohci_pci.c
+++ b/sys/dev/pci/ohci_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ohci_pci.c,v 1.32 2007/10/19 12:00:53 ad Exp $ */
+/* $NetBSD: ohci_pci.c,v 1.33 2007/12/09 20:28:11 jmcneill Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ohci_pci.c,v 1.32 2007/10/19 12:00:53 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ohci_pci.c,v 1.33 2007/12/09 20:28:11 jmcneill Exp $");
#include "ehci.h"
@@ -68,6 +68,7 @@ struct ohci_pci_softc {
struct usb_pci sc_pci;
#endif
pci_chipset_tag_t sc_pc;
+ pcitag_t sc_tag;
void *sc_ih; /* interrupt vectoring */
};
@@ -115,6 +116,7 @@ ohci_pci_attach(struct device *parent, struct device *self, void *aux)
OHCI_ALL_INTRS);
sc->sc_pc = pc;
+ sc->sc_tag = tag;
sc->sc.sc_bus.dmatag = pa->pa_dmat;
/* Enable the device. */
@@ -157,6 +159,9 @@ ohci_pci_attach(struct device *parent, struct device *self, void *aux)
usb_pci_add(&sc->sc_pci, pa, &sc->sc.sc_bus);
#endif
+ if (!pmf_device_register(self, ohci_suspend, ohci_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
/* Attach usb device. */
sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus,
usbctlprint);
diff --git a/sys/dev/pci/pccbb.c b/sys/dev/pci/pccbb.c
index d9c08f22f7d..e9e34d43dc2 100644
--- a/sys/dev/pci/pccbb.c
+++ b/sys/dev/pci/pccbb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pccbb.c,v 1.155 2007/12/01 05:41:53 jmcneill Exp $ */
+/* $NetBSD: pccbb.c,v 1.156 2007/12/09 20:28:11 jmcneill Exp $ */
/*
* Copyright (c) 1998, 1999 and 2000
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pccbb.c,v 1.155 2007/12/01 05:41:53 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pccbb.c,v 1.156 2007/12/09 20:28:11 jmcneill Exp $");
/*
#define CBB_DEBUG
@@ -185,7 +185,6 @@ static void pccbb_pcmcia_delay(struct pcic_handle *, int, const char *);
static void pccbb_pcmcia_do_io_map(struct pcic_handle *, int);
static void pccbb_pcmcia_do_mem_map(struct pcic_handle *, int);
-static void pccbb_powerhook(int, void *);
/* bus-space allocation and deallocation functions */
#if rbus
@@ -217,6 +216,9 @@ void pccbb_winlist_show(struct pccbb_win_chain *);
/* for config_defer */
static void pccbb_pci_callback(struct device *);
+static bool pccbb_suspend(device_t);
+static bool pccbb_resume(device_t);
+
#if defined SHOW_REGS
static void cb_show_regs(pci_chipset_tag_t pc, pcitag_t tag,
bus_space_tag_t memt, bus_space_handle_t memh);
@@ -378,36 +380,6 @@ cb_chipset(u_int32_t pci_id, int *flagp)
return (yc->yc_chiptype);
}
-static void
-pccbb_shutdown(void *arg)
-{
- struct pccbb_softc *sc = arg;
- pcireg_t command;
-
- DPRINTF(("%s: shutdown\n", sc->sc_dev.dv_xname));
-
- /*
- * turn off power
- *
- * XXX - do not turn off power if chipset is TI 113X because
- * only TI 1130 with PowerMac 2400 hangs in pccbb_power().
- */
- if (sc->sc_chipset != CB_TI113X) {
- pccbb_power((cardbus_chipset_tag_t)sc,
- CARDBUS_VCC_0V | CARDBUS_VPP_0V);
- }
-
- bus_space_write_4(sc->sc_base_memt, sc->sc_base_memh, CB_SOCKET_MASK,
- 0);
-
- command = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG);
-
- command &= ~(PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
- PCI_COMMAND_MASTER_ENABLE);
- pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG, command);
-
-}
-
void
pccbbattach(struct device *parent, struct device *self, void *aux)
{
@@ -418,7 +390,6 @@ pccbbattach(struct device *parent, struct device *self, void *aux)
bus_addr_t sockbase;
char devinfo[256];
int flags;
- int pwrmgt_offs;
#ifdef __HAVE_PCCBB_ATTACH_HOOK
pccbb_attach_hook(parent, self, pa);
@@ -452,23 +423,6 @@ pccbbattach(struct device *parent, struct device *self, void *aux)
sc->sc_flags &= ~CBB_MEMHMAPPED;
- /* power management: set D0 state */
- sc->sc_pwrmgt_offs = 0;
- if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT,
- &pwrmgt_offs, 0)) {
- reg = pci_conf_read(pc, pa->pa_tag, pwrmgt_offs + PCI_PMCSR);
- if ((reg & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_STATE_D0 ||
- reg & 0x100 /* PCI_PMCSR_PME_EN */) {
- reg &= ~PCI_PMCSR_STATE_MASK;
- reg |= PCI_PMCSR_STATE_D0;
- reg &= ~(0x100 /* PCI_PMCSR_PME_EN */);
- pci_conf_write(pc, pa->pa_tag,
- pwrmgt_offs + PCI_PMCSR, reg);
- }
-
- sc->sc_pwrmgt_offs = pwrmgt_offs;
- }
-
/*
* MAP socket registers and ExCA registers on memory-space
* When no valid address is set on socket base registers (on pci
@@ -526,15 +480,11 @@ pccbbattach(struct device *parent, struct device *self, void *aux)
sc->sc_dmat = pa->pa_dmat;
sc->sc_tag = pa->pa_tag;
sc->sc_function = pa->pa_function;
- sc->sc_sockbase = sock_base;
- sc->sc_busnum = busreg;
memcpy(&sc->sc_pa, pa, sizeof(*pa));
sc->sc_pcmcia_flags = flags; /* set PCMCIA facility */
- shutdownhook_establish(pccbb_shutdown, sc);
-
/* Disable legacy register mapping. */
switch (sc->sc_chipset) {
case CB_RX5C46X: /* fallthrough */
@@ -559,6 +509,9 @@ pccbbattach(struct device *parent, struct device *self, void *aux)
break;
}
+ if (!pmf_device_register(self, pccbb_suspend, pccbb_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
config_defer(self, pccbb_pci_callback);
}
@@ -618,7 +571,6 @@ pccbb_pci_callback(struct device *self)
sc->sc_dev.dv_xname, (unsigned long)sock_base,
(unsigned long)pci_conf_read(pc,
sc->sc_tag, PCI_SOCKBASE)));
- sc->sc_sockbase = sockbase;
#endif
sc->sc_flags |= CBB_MEMHMAPPED;
}
@@ -655,7 +607,6 @@ pccbb_pci_callback(struct device *self)
}
aprint_normal("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
- powerhook_establish(sc->sc_dev.dv_xname, pccbb_powerhook, sc);
{
u_int32_t sockstat;
@@ -3274,97 +3225,64 @@ pccbb_winset(bus_addr_t align, struct pccbb_softc *sc, bus_space_tag_t bst)
#endif /* rbus */
-static void
-pccbb_powerhook(int why, void *arg)
+static bool
+pccbb_suspend(device_t dv)
{
- struct pccbb_softc *sc = arg;
- pcireg_t reg;
+ struct pccbb_softc *sc = device_private(dv);
bus_space_tag_t base_memt = sc->sc_base_memt; /* socket regs memory */
bus_space_handle_t base_memh = sc->sc_base_memh;
+ pcireg_t reg;
- DPRINTF(("%s: power: why %d\n", sc->sc_dev.dv_xname, why));
-
- if (why == PWR_SUSPEND || why == PWR_STANDBY) {
- DPRINTF(("%s: power: why %d stopping intr\n",
- sc->sc_dev.dv_xname, why));
- if (sc->sc_pil_intr_enable) {
- (void)pccbbintr_function(sc);
- }
- sc->sc_pil_intr_enable = 0;
-
- pci_conf_capture(sc->sc_pc, sc->sc_tag, &sc->sc_pciconf);
-
- if (sc->sc_chipset == CB_RX5C47X)
- sc->sc_ricoh_misc_ctrl = pci_conf_read(sc->sc_pc,
- sc->sc_tag,
- RICOH_PCI_MISC_CTRL);
+ if (sc->sc_pil_intr_enable)
+ (void)pccbbintr_function(sc);
+ sc->sc_pil_intr_enable = 0;
- /* ToDo: deactivate or suspend child devices */
- }
+ reg = bus_space_read_4(base_memt, base_memh, CB_SOCKET_MASK);
+ /* Disable interrupts. */
+ reg &= ~(CB_SOCKET_MASK_CSTS | CB_SOCKET_MASK_CD | CB_SOCKET_MASK_POWER);
+ bus_space_write_4(base_memt, base_memh, CB_SOCKET_MASK, reg);
+ /* XXX joerg Disable power to the socket? */
- if (why == PWR_RESUME) {
- if (sc->sc_pwrmgt_offs != 0) {
- reg = pci_conf_read(sc->sc_pc, sc->sc_tag,
- sc->sc_pwrmgt_offs + PCI_PMCSR);
- if ((reg & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_STATE_D0 ||
- reg & PCI_PMCSR_PME_EN) {
- /* powrstate != D0 */
+ if (sc->sc_chipset == CB_RX5C47X)
+ sc->sc_ricoh_misc_ctrl = pci_conf_read(sc->sc_pc,
+ sc->sc_tag, RICOH_PCI_MISC_CTRL);
- printf("%s going back to D0 mode\n",
- sc->sc_dev.dv_xname);
- reg &= ~PCI_PMCSR_STATE_MASK;
- reg |= PCI_PMCSR_STATE_D0;
- reg &= ~PCI_PMCSR_PME_EN;
- pci_conf_write(sc->sc_pc, sc->sc_tag,
- sc->sc_pwrmgt_offs + PCI_PMCSR, reg);
-
- pci_conf_write(sc->sc_pc, sc->sc_tag,
- PCI_SOCKBASE, sc->sc_sockbase);
- pci_conf_write(sc->sc_pc, sc->sc_tag,
- PCI_BUSNUM, sc->sc_busnum);
- pccbb_chipinit(sc);
- /* setup memory and io space window for CB */
- pccbb_winset(0x1000, sc, sc->sc_memt);
- pccbb_winset(0x04, sc, sc->sc_iot);
- goto norestore;
- }
- }
+ return true;
+}
-norestore:
- pci_conf_restore(sc->sc_pc, sc->sc_tag, &sc->sc_pciconf);
- if (sc->sc_chipset == CB_RX5C47X) {
- pci_conf_write(sc->sc_pc, sc->sc_tag,
- RICOH_PCI_MISC_CTRL, sc->sc_ricoh_misc_ctrl);
- }
+static bool
+pccbb_resume(device_t dv)
+{
+ struct pccbb_softc *sc = device_private(dv);
+ bus_space_tag_t base_memt = sc->sc_base_memt; /* socket regs memory */
+ bus_space_handle_t base_memh = sc->sc_base_memh;
+ pcireg_t reg;
- if (pci_conf_read (sc->sc_pc, sc->sc_tag, PCI_SOCKBASE) == 0)
- /* BIOS did not recover this register */
- pci_conf_write (sc->sc_pc, sc->sc_tag,
- PCI_SOCKBASE, sc->sc_sockbase);
- if (pci_conf_read (sc->sc_pc, sc->sc_tag, PCI_BUSNUM) == 0)
- /* BIOS did not recover this register */
- pci_conf_write (sc->sc_pc, sc->sc_tag,
- PCI_BUSNUM, sc->sc_busnum);
- /* CSC Interrupt: Card detect interrupt on */
- reg = bus_space_read_4(base_memt, base_memh, CB_SOCKET_MASK);
- /* Card detect intr is turned on. */
- reg |= CB_SOCKET_MASK_CD | CB_SOCKET_MASK_POWER;
- bus_space_write_4(base_memt, base_memh, CB_SOCKET_MASK, reg);
- /* reset interrupt */
- reg = bus_space_read_4(base_memt, base_memh, CB_SOCKET_EVENT);
- bus_space_write_4(base_memt, base_memh, CB_SOCKET_EVENT, reg);
+ pccbb_chipinit(sc);
+ /* setup memory and io space window for CB */
+ pccbb_winset(0x1000, sc, sc->sc_memt);
+ pccbb_winset(0x04, sc, sc->sc_iot);
+ if (sc->sc_chipset == CB_RX5C47X)
+ pci_conf_write(sc->sc_pc, sc->sc_tag,
+ RICOH_PCI_MISC_CTRL, sc->sc_ricoh_misc_ctrl);
+
+ /* CSC Interrupt: Card detect interrupt on */
+ reg = bus_space_read_4(base_memt, base_memh, CB_SOCKET_MASK);
+ /* Card detect intr is turned on. */
+ reg |= CB_SOCKET_MASK_CD | CB_SOCKET_MASK_POWER;
+ bus_space_write_4(base_memt, base_memh, CB_SOCKET_MASK, reg);
+ /* reset interrupt */
+ reg = bus_space_read_4(base_memt, base_memh, CB_SOCKET_EVENT);
+ bus_space_write_4(base_memt, base_memh, CB_SOCKET_EVENT, reg);
- /*
- * check for card insertion or removal during suspend period.
- * XXX: the code can't cope with card swap (remove then
- * insert). how can we detect such situation?
- */
- (void)pccbbintr(sc);
+ /*
+ * check for card insertion or removal during suspend period.
+ * XXX: the code can't cope with card swap (remove then
+ * insert). how can we detect such situation?
+ */
+ (void)pccbbintr(sc);
- sc->sc_pil_intr_enable = 1;
- DPRINTF(("%s: power: RESUME enabling intr\n",
- sc->sc_dev.dv_xname));
+ sc->sc_pil_intr_enable = 1;
- /* ToDo: activate or wakeup child devices */
- }
+ return true;
}
diff --git a/sys/dev/pci/pccbbvar.h b/sys/dev/pci/pccbbvar.h
index 5dcfe285a89..2a26c932293 100644
--- a/sys/dev/pci/pccbbvar.h
+++ b/sys/dev/pci/pccbbvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: pccbbvar.h,v 1.29 2007/08/10 22:57:54 dyoung Exp $ */
+/* $NetBSD: pccbbvar.h,v 1.30 2007/12/09 20:28:11 jmcneill Exp $ */
/*
* Copyright (c) 1999 HAYAKAWA Koichi. All rights reserved.
*
@@ -132,9 +132,6 @@ struct pccbb_softc {
bus_addr_t sc_io_start; /* CardBus/PCMCIA io start */
bus_addr_t sc_io_end; /* CardBus/PCMCIA io end */
- pcireg_t sc_sockbase; /* Socket base register */
- pcireg_t sc_busnum; /* bus number */
-
/* CardBus stuff */
struct cardslot_softc *sc_csc;
@@ -156,8 +153,6 @@ struct pccbb_softc {
LIST_HEAD(, pccbb_intrhand_list) sc_pil;
int sc_pil_intr_enable; /* can i call intr handler for child device? */
- int sc_pwrmgt_offs; /* Offset for power management capability */
- struct pci_conf_state sc_pciconf;
pcireg_t sc_ricoh_misc_ctrl;
};
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 7b06067b205..87211c3708d 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pci.c,v 1.106 2007/12/01 16:46:18 ad Exp $ */
+/* $NetBSD: pci.c,v 1.107 2007/12/09 20:28:11 jmcneill Exp $ */
/*
* Copyright (c) 1995, 1996, 1997, 1998
@@ -36,11 +36,12 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.106 2007/12/01 16:46:18 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.107 2007/12/09 20:28:11 jmcneill Exp $");
#include "opt_pci.h"
#include <sys/param.h>
+#include <sys/malloc.h>
#include <sys/systm.h>
#include <sys/device.h>
@@ -50,8 +51,12 @@ __KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.106 2007/12/01 16:46:18 ad Exp $");
#include <uvm/uvm_extern.h>
+#include <net/if.h>
+
#include "locators.h"
+static bool pci_child_register(device_t);
+
#ifdef PCI_CONFIG_DUMP
int pci_config_dump = 1;
#else
@@ -126,86 +131,6 @@ pcimatch(struct device *parent, struct cfdata *cf, void *aux)
}
static void
-pci_power_devices(struct pci_softc *sc, int why)
-{
- pci_chipset_tag_t pc;
- int device, function, nfunctions;
- pcitag_t tag;
- pcireg_t bhlcr, id;
- pcireg_t state;
-#ifdef __PCI_BUS_DEVORDER
- char devs[32];
- int i;
-#endif
-
- pc = sc->sc_pc;
- switch (why) {
- case PWR_STANDBY:
- state = PCI_PMCSR_STATE_D1;
- break;
- case PWR_SUSPEND:
- state = PCI_PMCSR_STATE_D3;
- break;
- case PWR_RESUME:
- state = PCI_PMCSR_STATE_D0;
- break;
- default:
- /* we should never be called here */
-#ifdef DIAGNOSTIC
- panic("pci_power_devices called with invalid reason %d\n",
- why);
- /* NOTREACHED */
-#endif
- return;
- }
-
-#ifdef __PCI_BUS_DEVORDER
- pci_bus_devorder(sc->sc_pc, sc->sc_bus, devs);
- for (i = 0; (device = devs[i]) < 32 && device >= 0; i++)
-#else
- for (device = 0; device < sc->sc_maxndevs; device++)
-#endif
- {
- tag = pci_make_tag(pc, sc->sc_bus, device, 0);
- bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG);
- if (PCI_HDRTYPE_TYPE(bhlcr) > 2)
- continue;
- id = pci_conf_read(pc, tag, PCI_ID_REG);
- if (PCI_VENDOR(id) == PCI_VENDOR_INVALID ||
- PCI_VENDOR(id) == 0x0000)
- continue;
- nfunctions = PCI_HDRTYPE_MULTIFN(bhlcr) ? 8 : 1;
-
- for (function = 0; function < nfunctions; function++) {
- tag = pci_make_tag(pc, sc->sc_bus, device, function);
- if (sc->PCI_SC_DEVICESC(device, function) != NULL)
- continue;
- (void)pci_set_powerstate(pc, tag, state);
- }
- }
-
- return;
-}
-
-static void
-pci_powerhook(int why, void *aux)
-{
- struct pci_softc *sc;
-
- sc = (struct pci_softc *)aux;
-
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- case PWR_RESUME:
- pci_power_devices(sc, why);
- break;
- }
-
- return;
-}
-
-static void
pciattach(struct device *parent, struct device *self, void *aux)
{
struct pcibus_attach_args *pba = aux;
@@ -229,7 +154,7 @@ pciattach(struct device *parent, struct device *self, void *aux)
if (io_enabled == 0 && mem_enabled == 0) {
aprint_error("%s: no spaces enabled!\n", self->dv_xname);
- return;
+ goto fail;
}
#define PRINT(str) \
@@ -272,13 +197,20 @@ do { \
sc->sc_intrtag = pba->pba_intrtag;
sc->sc_flags = pba->pba_flags;
- sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- pci_powerhook, sc);
- if (sc->sc_powerhook == NULL)
- aprint_error("%s: can't establish powerhook\n",
- sc->sc_dev.dv_xname);
+ device_pmf_driver_set_child_register(&sc->sc_dev, pci_child_register);
pcirescan(&sc->sc_dev, "pci", wildcard);
+
+fail:
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+}
+
+static int
+pcidetach(struct device *self, int flags)
+{
+ pmf_device_deregister(self);
+ return 0;
}
int
@@ -447,6 +379,9 @@ pcidevdetached(struct device *sc, struct device *dev)
psc->PCI_SC_DEVICESC(d, f) = 0;
}
+CFATTACH_DECL2(pci, sizeof(struct pci_softc),
+ pcimatch, pciattach, pcidetach, NULL, pcirescan, pcidevdetached);
+
int
pci_get_capability(pci_chipset_tag_t pc, pcitag_t tag, int capid,
int *offset, pcireg_t *value)
@@ -694,9 +629,13 @@ pci_conf_restore(pci_chipset_tag_t pc, pcitag_t tag,
struct pci_conf_state *pcs)
{
int off;
+ pcireg_t val;
- for (off = 0; off < 16; off++)
- pci_conf_write(pc, tag, (off * 4), pcs->reg[off]);
+ for (off = 15; off >= 0; off--) {
+ val = pci_conf_read(pc, tag, (off * 4));
+ if (val != pcs->reg[off])
+ pci_conf_write(pc, tag, (off * 4), pcs->reg[off]);
+ }
return;
}
@@ -704,16 +643,12 @@ pci_conf_restore(pci_chipset_tag_t pc, pcitag_t tag,
/*
* Power Management Capability (Rev 2.2)
*/
-int
-pci_get_powerstate(pci_chipset_tag_t pc, pcitag_t tag , pcireg_t *state)
+static int
+pci_get_powerstate_int(pci_chipset_tag_t pc, pcitag_t tag , pcireg_t *state,
+ int offset)
{
- int offset;
- pcireg_t value, cap, now;
+ pcireg_t value, 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) {
@@ -729,15 +664,24 @@ pci_get_powerstate(pci_chipset_tag_t pc, pcitag_t tag , pcireg_t *state)
}
int
-pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag, pcireg_t state)
+pci_get_powerstate(pci_chipset_tag_t pc, pcitag_t tag , pcireg_t *state)
{
int offset;
- pcireg_t value, cap, now;
+ pcireg_t value;
if (!pci_get_capability(pc, tag, PCI_CAP_PWRMGMT, &offset, &value))
return EOPNOTSUPP;
- cap = value >> PCI_PMCR_SHIFT;
+ return pci_get_powerstate_int(pc, tag, state, offset);
+}
+
+static int
+pci_set_powerstate_int(pci_chipset_tag_t pc, pcitag_t tag, pcireg_t state,
+ int offset, pcireg_t cap_reg)
+{
+ pcireg_t value, cap, now;
+
+ cap = cap_reg >> PCI_PMCR_SHIFT;
value = pci_conf_read(pc, tag, offset + PCI_PMCSR);
now = value & PCI_PMCSR_STATE_MASK;
value &= ~PCI_PMCSR_STATE_MASK;
@@ -749,22 +693,28 @@ pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag, pcireg_t state)
value |= PCI_PMCSR_STATE_D0;
break;
case PCI_PMCSR_STATE_D1:
- if (now == PCI_PMCSR_STATE_D2 || now == PCI_PMCSR_STATE_D3)
+ if (now == PCI_PMCSR_STATE_D2 || now == PCI_PMCSR_STATE_D3) {
+ printf("invalid transition from %d to D1\n", (int)now);
return EINVAL;
- if (!(cap & PCI_PMCR_D1SUPP))
+ }
+ if (!(cap & PCI_PMCR_D1SUPP)) {
+ printf("D1 not supported\n");
return EOPNOTSUPP;
+ }
value |= PCI_PMCSR_STATE_D1;
break;
case PCI_PMCSR_STATE_D2:
- if (now == PCI_PMCSR_STATE_D3)
+ if (now == PCI_PMCSR_STATE_D3) {
+ printf("invalid transition from %d to D2\n", (int)now);
return EINVAL;
- if (!(cap & PCI_PMCR_D2SUPP))
+ }
+ if (!(cap & PCI_PMCR_D2SUPP)) {
+ printf("D2 not supported\n");
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:
@@ -776,6 +726,20 @@ pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag, pcireg_t state)
}
int
+pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag, pcireg_t state)
+{
+ int offset;
+ pcireg_t value;
+
+ if (!pci_get_capability(pc, tag, PCI_CAP_PWRMGMT, &offset, &value)) {
+ printf("pci_set_powerstate not supported\n");
+ return EOPNOTSUPP;
+ }
+
+ return pci_set_powerstate_int(pc, tag, state, offset, value);
+}
+
+int
pci_activate(pci_chipset_tag_t pc, pcitag_t tag, void *sc,
int (*wakefun)(pci_chipset_tag_t, pcitag_t, void *, pcireg_t))
{
@@ -822,9 +786,6 @@ pci_activate_null(pci_chipset_tag_t pc, pcitag_t tag,
return 0;
}
-CFATTACH_DECL2(pci, sizeof(struct pci_softc),
- pcimatch, pciattach, NULL, NULL, pcirescan, pcidevdetached);
-
void
pci_disable_retry(pci_chipset_tag_t pc, pcitag_t tag)
{
@@ -838,3 +799,90 @@ pci_disable_retry(pci_chipset_tag_t pc, pcitag_t tag)
retry &= ~PCI_RETRY_TIMEOUT_REG_MASK;
pci_conf_write(pc, tag, PCI_RETRY_TIMEOUT_REG, retry);
}
+
+struct pci_child_power {
+ struct pci_conf_state p_pciconf;
+ pci_chipset_tag_t p_pc;
+ pcitag_t p_tag;
+ bool p_has_pm;
+ int p_pm_offset;
+ pcireg_t p_pm_cap;
+ pcireg_t p_class;
+};
+
+static bool
+pci_child_suspend(device_t dv)
+{
+ struct pci_child_power *priv = device_pmf_bus_private(dv);
+
+ pci_conf_capture(priv->p_pc, priv->p_tag, &priv->p_pciconf);
+
+ if (priv->p_has_pm &&
+ PCI_CLASS(priv->p_class) != PCI_CLASS_DISPLAY &&
+ pci_set_powerstate_int(priv->p_pc, priv->p_tag,
+ PCI_PMCSR_STATE_D3, priv->p_pm_offset, priv->p_pm_cap)) {
+ aprint_error_dev(dv, "unsupported state, continuing.\n");
+ return false;
+ }
+ return true;
+}
+
+static bool
+pci_child_resume(device_t dv)
+{
+ struct pci_child_power *priv = device_pmf_bus_private(dv);
+
+ if (priv->p_has_pm &&
+ pci_set_powerstate_int(priv->p_pc, priv->p_tag,
+ PCI_PMCSR_STATE_D0, priv->p_pm_offset, priv->p_pm_cap)) {
+ aprint_error_dev(dv, "unsupported state, continuing.\n");
+ return false;
+ }
+
+ pci_conf_restore(priv->p_pc, priv->p_tag, &priv->p_pciconf);
+
+ return true;
+}
+
+static void
+pci_child_deregister(device_t dv)
+{
+ struct pci_child_power *priv = device_pmf_bus_private(dv);
+
+ free(priv, M_DEVBUF);
+}
+
+static bool
+pci_child_register(device_t child)
+{
+ device_t self = device_parent(child);
+ struct pci_softc *sc = device_private(self);
+ struct pci_child_power *priv;
+ int device, function, off;
+ pcireg_t reg;
+
+ priv = malloc(sizeof(*priv), M_DEVBUF, M_WAITOK);
+
+ device = device_locator(child, PCICF_DEV);
+ function = device_locator(child, PCICF_FUNCTION);
+
+ priv->p_pc = sc->sc_pc;
+ priv->p_tag = pci_make_tag(priv->p_pc, sc->sc_bus, device,
+ function);
+ priv->p_class = pci_conf_read(priv->p_pc, priv->p_tag, PCI_CLASS_REG);
+
+ if (pci_get_capability(priv->p_pc, priv->p_tag,
+ PCI_CAP_PWRMGMT, &off, &reg)) {
+ priv->p_has_pm = true;
+ priv->p_pm_offset = off;
+ priv->p_pm_cap = reg;
+ } else {
+ priv->p_has_pm = false;
+ priv->p_pm_offset = -1;
+ }
+
+ device_pmf_bus_register(child, priv, pci_child_suspend,
+ pci_child_resume, pci_child_deregister);
+
+ return true;
+}
diff --git a/sys/dev/pci/pcidevs.h b/sys/dev/pci/pcidevs.h
index 723ada15ef0..a32e0d507e5 100644
--- a/sys/dev/pci/pcidevs.h
+++ b/sys/dev/pci/pcidevs.h
@@ -1,10 +1,10 @@
-/* $NetBSD: pcidevs.h,v 1.920 2007/11/26 09:36:29 bjs Exp $ */
+/* $NetBSD: pcidevs.h,v 1.921 2007/12/09 20:28:12 jmcneill Exp $ */
/*
* THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
*
* generated from:
- * NetBSD: pcidevs,v 1.919 2007/11/24 01:44:55 markd Exp
+ * NetBSD: pcidevs,v 1.885.6.10 2007/10/31 23:14:07 joerg Exp
*/
/*
diff --git a/sys/dev/pci/pcidevs_data.h b/sys/dev/pci/pcidevs_data.h
index 1268e2692f0..3e4a873da5a 100644
--- a/sys/dev/pci/pcidevs_data.h
+++ b/sys/dev/pci/pcidevs_data.h
@@ -1,10 +1,10 @@
-/* $NetBSD: pcidevs_data.h,v 1.919 2007/11/26 09:36:29 bjs Exp $ */
+/* $NetBSD: pcidevs_data.h,v 1.920 2007/12/09 20:28:12 jmcneill Exp $ */
/*
* THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
*
* generated from:
- * NetBSD: pcidevs,v 1.919 2007/11/24 01:44:55 markd Exp
+ * NetBSD: pcidevs,v 1.885.6.10 2007/10/31 23:14:07 joerg Exp
*/
/*
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
index 27b39cfd334..69900d1601f 100644
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: pcivar.h,v 1.76 2007/11/12 19:54:36 joerg Exp $ */
+/* $NetBSD: pcivar.h,v 1.77 2007/12/09 20:28:12 jmcneill Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@@ -42,6 +42,7 @@
*/
#include <sys/device.h>
+#include <sys/pmf.h>
#include <sys/bus.h>
#include <dev/pci/pcireg.h>
@@ -169,7 +170,6 @@ struct pci_softc {
/* accounting of child devices */
struct device *sc_devices[32*8];
#define PCI_SC_DEVICESC(d, f) sc_devices[(d) * 8 + (f)]
- void *sc_powerhook;
};
struct pci_conf_state {
diff --git a/sys/dev/pci/piixide.c b/sys/dev/pci/piixide.c
index edb236ad8fe..3c449b8185c 100644
--- a/sys/dev/pci/piixide.c
+++ b/sys/dev/pci/piixide.c
@@ -1,4 +1,4 @@
-/* $NetBSD: piixide.c,v 1.41 2007/09/09 01:09:02 xtraeme Exp $ */
+/* $NetBSD: piixide.c,v 1.42 2007/12/09 20:28:12 jmcneill Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Manuel Bouyer.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: piixide.c,v 1.41 2007/09/09 01:09:02 xtraeme Exp $");
+__KERNEL_RCSID(0, "$NetBSD: piixide.c,v 1.42 2007/12/09 20:28:12 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -50,7 +50,8 @@ static u_int32_t piix_setup_sidetim_timings(u_int8_t, u_int8_t, u_int8_t);
static void piixsata_chip_map(struct pciide_softc*, struct pci_attach_args *);
static int piix_dma_init(void *, int, int, void *, size_t, int);
-static void piixide_powerhook(int, void *);
+static bool piixide_resume(device_t);
+static bool piixide_suspend(device_t);
static int piixide_match(struct device *, struct cfdata *, void *);
static void piixide_attach(struct device *, struct device *, void *);
@@ -277,42 +278,34 @@ piixide_attach(struct device *parent, struct device *self, void *aux)
pciide_common_attach(sc, pa,
pciide_lookup_product(pa->pa_id, pciide_intel_products));
- /* Setup our powerhook */
- sc->sc_powerhook = powerhook_establish(
- sc->sc_wdcdev.sc_atac.atac_dev.dv_xname, piixide_powerhook, sc);
- if (sc->sc_powerhook == NULL)
- printf("%s: WARNING: unable to establish PCI power hook\n",
- sc->sc_wdcdev.sc_atac.atac_dev.dv_xname);
+ if (!pmf_device_register(self, piixide_suspend, piixide_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
-static void
-piixide_powerhook(int why, void *hdl)
+static bool
+piixide_resume(device_t dv)
{
- struct pciide_softc *sc = (struct pciide_softc *)hdl;
-
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- pci_conf_capture(sc->sc_pc, sc->sc_tag, &sc->sc_pciconf);
- sc->sc_idetim = pci_conf_read(sc->sc_pc, sc->sc_tag,
- PIIX_IDETIM);
- sc->sc_udmatim = pci_conf_read(sc->sc_pc, sc->sc_tag,
- PIIX_UDMATIM);
- break;
- case PWR_RESUME:
- pci_conf_restore(sc->sc_pc, sc->sc_tag, &sc->sc_pciconf);
- pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_IDETIM,
- sc->sc_idetim);
- pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_UDMATIM,
- sc->sc_udmatim);
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
- }
+ struct pciide_softc *sc = device_private(dv);
+
+ pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_IDETIM,
+ sc->sc_idetim);
+ pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_UDMATIM,
+ sc->sc_udmatim);
+
+ return true;
+}
+
+static bool
+piixide_suspend(device_t dv)
+{
+ struct pciide_softc *sc = device_private(dv);
+
+ sc->sc_idetim = pci_conf_read(sc->sc_pc, sc->sc_tag,
+ PIIX_IDETIM);
+ sc->sc_udmatim = pci_conf_read(sc->sc_pc, sc->sc_tag,
+ PIIX_UDMATIM);
- return;
+ return true;
}
static void
diff --git a/sys/dev/pci/piixpm.c b/sys/dev/pci/piixpm.c
index 01e316c7cc9..019a997c733 100644
--- a/sys/dev/pci/piixpm.c
+++ b/sys/dev/pci/piixpm.c
@@ -1,4 +1,4 @@
-/* $NetBSD: piixpm.c,v 1.17 2007/10/19 12:00:54 ad Exp $ */
+/* $NetBSD: piixpm.c,v 1.18 2007/12/09 20:28:13 jmcneill Exp $ */
/* $OpenBSD: piixpm.c,v 1.20 2006/02/27 08:25:02 grange Exp $ */
/*
@@ -73,15 +73,14 @@ struct piixpm_softc {
volatile int error;
} sc_i2c_xfer;
- void * sc_powerhook;
- struct pci_conf_state sc_pciconf;
pcireg_t sc_devact[2];
};
int piixpm_match(struct device *, struct cfdata *, void *);
void piixpm_attach(struct device *, struct device *, void *);
-void piixpm_powerhook(int, void *);
+static bool piixpm_suspend(device_t);
+static bool piixpm_resume(device_t);
int piixpm_i2c_acquire_bus(void *, int);
void piixpm_i2c_release_bus(void *, int);
@@ -150,11 +149,8 @@ piixpm_attach(struct device *parent, struct device *self, void *aux)
aprint_normal("\n%s: %s (rev. 0x%02x)\n",
device_xname(self), devinfo, PCI_REVISION(pa->pa_class));
- sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- piixpm_powerhook, sc);
- if (sc->sc_powerhook == NULL)
- aprint_error("%s: can't establish powerhook\n",
- sc->sc_dev.dv_xname);
+ if (!pmf_device_register(self, piixpm_suspend, piixpm_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
/* Read configuration */
conf = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_HOSTC);
@@ -240,27 +236,30 @@ nopowermanagement:
return;
}
-void
-piixpm_powerhook(int why, void *cookie)
+static bool
+piixpm_suspend(device_t dv)
{
- struct piixpm_softc *sc = cookie;
- pci_chipset_tag_t pc = sc->sc_pc;
- pcitag_t tag = sc->sc_pcitag;
-
- switch (why) {
- case PWR_SUSPEND:
- pci_conf_capture(pc, tag, &sc->sc_pciconf);
- sc->sc_devact[0] = pci_conf_read(pc, tag, PIIX_DEVACTA);
- sc->sc_devact[1] = pci_conf_read(pc, tag, PIIX_DEVACTB);
- break;
- case PWR_RESUME:
- pci_conf_restore(pc, tag, &sc->sc_pciconf);
- pci_conf_write(pc, tag, PIIX_DEVACTA, sc->sc_devact[0]);
- pci_conf_write(pc, tag, PIIX_DEVACTB, sc->sc_devact[1]);
- break;
- }
+ struct piixpm_softc *sc = device_private(dv);
- return;
+ sc->sc_devact[0] = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
+ PIIX_DEVACTA);
+ sc->sc_devact[1] = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
+ PIIX_DEVACTB);
+
+ return true;
+}
+
+static bool
+piixpm_resume(device_t dv)
+{
+ struct piixpm_softc *sc = device_private(dv);
+
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_DEVACTA,
+ sc->sc_devact[0]);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_DEVACTB,
+ sc->sc_devact[1]);
+
+ return true;
}
int
diff --git a/sys/dev/pci/ppb.c b/sys/dev/pci/ppb.c
index be881da2510..ce4e4e5bbe6 100644
--- a/sys/dev/pci/ppb.c
+++ b/sys/dev/pci/ppb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ppb.c,v 1.35 2007/10/16 18:27:00 joerg Exp $ */
+/* $NetBSD: ppb.c,v 1.36 2007/12/09 20:28:13 jmcneill Exp $ */
/*
* Copyright (c) 1996, 1998 Christopher G. Demetriou. All rights reserved.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ppb.c,v 1.35 2007/10/16 18:27:00 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ppb.c,v 1.36 2007/12/09 20:28:13 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -41,13 +41,19 @@ __KERNEL_RCSID(0, "$NetBSD: ppb.c,v 1.35 2007/10/16 18:27:00 joerg Exp $");
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/ppbreg.h>
+#include <dev/pci/pcidevs.h>
struct ppb_softc {
struct device sc_dev; /* generic device glue */
pci_chipset_tag_t sc_pc; /* our PCI chipset... */
pcitag_t sc_tag; /* ...and tag. */
+
+ pcireg_t sc_pciconfext[48];
};
+static bool ppb_resume(device_t);
+static bool ppb_suspend(device_t);
+
static int
ppbmatch(struct device *parent, struct cfdata *match,
void *aux)
@@ -67,12 +73,13 @@ ppbmatch(struct device *parent, struct cfdata *match,
}
static void
-ppb_fix_pcix(device_t self, struct pci_attach_args *pa)
+ppb_fix_pcix(device_t self)
{
+ struct ppb_softc *sc = device_private(self);
pcireg_t reg;
int off;
- if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIEXPRESS,
+ if (!pci_get_capability(sc->sc_pc, sc->sc_tag, PCI_CAP_PCIEXPRESS,
&off, &reg))
return; /* Not a PCIe device */
@@ -80,11 +87,11 @@ ppb_fix_pcix(device_t self, struct pci_attach_args *pa)
aprint_normal_dev(self, "unuspported PCI Express version\n");
return;
}
- reg = pci_conf_read(pa->pa_pc, pa->pa_tag, off + 0x18);
+ reg = pci_conf_read(sc->sc_pc, sc->sc_tag, off + 0x18);
if (reg & 0x003f) {
aprint_normal_dev(self, "disabling notification events\n");
reg &= ~0x003f;
- pci_conf_write(pa->pa_pc, pa->pa_tag, off + 0x18, reg);
+ pci_conf_write(sc->sc_pc, sc->sc_tag, off + 0x18, reg);
}
}
@@ -114,7 +121,7 @@ ppbattach(struct device *parent, struct device *self, void *aux)
return;
}
- ppb_fix_pcix(self, pa);
+ ppb_fix_pcix(self);
#if 0
/*
@@ -128,6 +135,9 @@ ppbattach(struct device *parent, struct device *self, void *aux)
pa->pa_bus, PPB_BUSINFO_PRIMARY(busdata));
#endif
+ if (!pmf_device_register(self, ppb_suspend, ppb_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
/*
* Attach the PCI bus than hangs off of it.
*
@@ -148,5 +158,37 @@ ppbattach(struct device *parent, struct device *self, void *aux)
config_found_ia(self, "pcibus", &pba, pcibusprint);
}
+static bool
+ppb_resume(device_t dv)
+{
+ struct ppb_softc *sc = device_private(dv);
+ int off;
+ pcireg_t val;
+
+ for (off = 0x40; off <= 0xff; off += 4) {
+ val = pci_conf_read(sc->sc_pc, sc->sc_tag, off);
+ if (val != sc->sc_pciconfext[(off - 0x40) / 4])
+ pci_conf_write(sc->sc_pc, sc->sc_tag, off,
+ sc->sc_pciconfext[(off - 0x40)/4]);
+ }
+
+ ppb_fix_pcix(dv);
+
+ return true;
+}
+
+static bool
+ppb_suspend(device_t dv)
+{
+ struct ppb_softc *sc = device_private(dv);
+ int off;
+
+ for (off = 0x40; off <= 0xff; off += 4)
+ sc->sc_pciconfext[(off - 0x40) / 4] =
+ pci_conf_read(sc->sc_pc, sc->sc_tag, off);
+
+ return true;
+}
+
CFATTACH_DECL(ppb, sizeof(struct ppb_softc),
ppbmatch, ppbattach, NULL, NULL);
diff --git a/sys/dev/pci/uhci_pci.c b/sys/dev/pci/uhci_pci.c
index 5487e82e980..da4b535d296 100644
--- a/sys/dev/pci/uhci_pci.c
+++ b/sys/dev/pci/uhci_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: uhci_pci.c,v 1.39 2007/11/25 02:46:54 dsainty Exp $ */
+/* $NetBSD: uhci_pci.c,v 1.40 2007/12/09 20:28:13 jmcneill Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhci_pci.c,v 1.39 2007/11/25 02:46:54 dsainty Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhci_pci.c,v 1.40 2007/12/09 20:28:13 jmcneill Exp $");
#include "ehci.h"
@@ -62,7 +62,7 @@ __KERNEL_RCSID(0, "$NetBSD: uhci_pci.c,v 1.39 2007/11/25 02:46:54 dsainty Exp $"
#include <dev/usb/uhcireg.h>
#include <dev/usb/uhcivar.h>
-static void uhci_pci_powerhook(int, void *);
+static bool uhci_pci_resume(device_t);
struct uhci_pci_softc {
uhci_softc_t sc;
@@ -72,9 +72,6 @@ struct uhci_pci_softc {
pci_chipset_tag_t sc_pc;
pcitag_t sc_tag;
void *sc_ih; /* interrupt vectoring */
-
- void *sc_powerhook;
- struct pci_conf_state sc_pciconf;
};
static int
@@ -189,15 +186,6 @@ uhci_pci_attach(struct device *parent, struct device *self, void *aux)
snprintf(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor),
"vendor 0x%04x", PCI_VENDOR(pa->pa_id));
- /*
- * Establish our powerhook before uhci_init() does its powerhook.
- */
- sc->sc_powerhook = powerhook_establish(USBDEVNAME(sc->sc.sc_bus.bdev),
- uhci_pci_powerhook, sc);
- if (sc->sc_powerhook == NULL)
- aprint_error("%s: couldn't establish powerhook\n",
- devname);
-
r = uhci_init(&sc->sc);
if (r != USBD_NORMAL_COMPLETION) {
aprint_error("%s: init failed, error=%d\n", devname, r);
@@ -208,6 +196,9 @@ uhci_pci_attach(struct device *parent, struct device *self, void *aux)
usb_pci_add(&sc->sc_pci, pa, &sc->sc.sc_bus);
#endif
+ if (!pmf_device_register(self, uhci_suspend, uhci_pci_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
/* Attach usb device. */
sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus,
usbctlprint);
@@ -219,8 +210,7 @@ uhci_pci_detach(device_ptr_t self, int flags)
struct uhci_pci_softc *sc = (struct uhci_pci_softc *)self;
int rv;
- if (sc->sc_powerhook != NULL)
- powerhook_disestablish(sc->sc_powerhook);
+ pmf_device_deregister(self);
rv = uhci_detach(&sc->sc, flags);
if (rv)
@@ -239,34 +229,16 @@ uhci_pci_detach(device_ptr_t self, int flags)
return (0);
}
-static void
-uhci_pci_powerhook(int why, void *opaque)
+static bool
+uhci_pci_resume(device_t dv)
{
- struct uhci_pci_softc *sc;
- pci_chipset_tag_t pc;
- pcitag_t tag;
- pcireg_t reg;
-
- sc = (struct uhci_pci_softc *)opaque;
- pc = sc->sc_pc;
- tag = sc->sc_tag;
-
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- pci_conf_capture(pc, tag, &sc->sc_pciconf);
- break;
- case PWR_RESUME:
- pci_conf_restore(pc, tag, &sc->sc_pciconf);
- /* the BIOS might change this on us */
- reg = pci_conf_read(pc, tag, PCI_LEGSUP);
- reg |= PCI_LEGSUP_USBPIRQDEN;
- reg &= ~PCI_LEGSUP_USBSMIEN;
- pci_conf_write(pc, tag, PCI_LEGSUP, reg);
- break;
- }
+ struct uhci_pci_softc *sc = device_private(dv);
+
+ /* Set LEGSUP register to its default value. */
+ pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_LEGSUP,
+ PCI_LEGSUP_USBPIRQDEN);
- return;
+ return uhci_resume(dv);
}
CFATTACH_DECL(uhci_pci, sizeof(struct uhci_pci_softc),
diff --git a/sys/dev/pci/vga_pci.c b/sys/dev/pci/vga_pci.c
index 17f9714dfdb..f45ddf9274a 100644
--- a/sys/dev/pci/vga_pci.c
+++ b/sys/dev/pci/vga_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: vga_pci.c,v 1.36 2007/12/01 17:00:41 ad Exp $ */
+/* $NetBSD: vga_pci.c,v 1.37 2007/12/09 20:28:13 jmcneill Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vga_pci.c,v 1.36 2007/12/01 17:00:41 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vga_pci.c,v 1.37 2007/12/09 20:28:13 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -69,11 +69,14 @@ struct vga_pci_softc {
struct vga_bar sc_bars[NBARS];
struct vga_bar sc_rom;
+
+ struct pci_conf_state sc_pciconf;
};
static int vga_pci_match(struct device *, struct cfdata *, void *);
static void vga_pci_attach(struct device *, struct device *, void *);
static int vga_pci_lookup_quirks(struct pci_attach_args *);
+static bool vga_pci_resume(device_t dv);
CFATTACH_DECL(vga_pci, sizeof(struct vga_pci_softc),
vga_pci_match, vga_pci_attach, NULL, NULL);
@@ -218,9 +221,26 @@ vga_pci_attach(struct device *parent, struct device *self, void *aux)
vga_common_attach(sc, pa->pa_iot, pa->pa_memt, WSDISPLAY_TYPE_PCIVGA,
vga_pci_lookup_quirks(pa), &vga_pci_funcs);
+ /*
+ * XXX Do not use the generic PCI framework for now as
+ * XXX it would power down the device when the console
+ * XXX is still using it.
+ */
+ if (!pmf_device_register(self, NULL, vga_pci_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
config_found_ia(self, "drm", aux, vga_drm_print);
}
+static bool
+vga_pci_resume(device_t dv)
+{
+ struct vga_pci_softc *sc = device_private(dv);
+
+ vga_resume(&sc->sc_vga);
+
+ return true;
+}
+
int
vga_pci_cnattach(bus_space_tag_t iot, bus_space_tag_t memt,
pci_chipset_tag_t pc, int bus, int device,
diff --git a/sys/dev/pci/yds.c b/sys/dev/pci/yds.c
index 08cb974906e..cac1c10ffa4 100644
--- a/sys/dev/pci/yds.c
+++ b/sys/dev/pci/yds.c
@@ -1,4 +1,4 @@
-/* $NetBSD: yds.c,v 1.38 2007/10/19 12:00:56 ad Exp $ */
+/* $NetBSD: yds.c,v 1.39 2007/12/09 20:28:13 jmcneill Exp $ */
/*
* Copyright (c) 2000, 2001 Kazuki Sakamoto and Minoura Makoto.
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: yds.c,v 1.38 2007/10/19 12:00:56 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: yds.c,v 1.39 2007/12/09 20:28:13 jmcneill Exp $");
#include "mpu.h"
@@ -192,7 +192,6 @@ static uint32_t yds_get_lpfk(u_int);
static struct yds_dma *yds_find_dma(struct yds_softc *, void *);
static int yds_init(struct yds_softc *);
-static void yds_powerhook(int, void *);
#ifdef AUDIO_DEBUG
static void yds_dump_play_slot(struct yds_softc *, int);
@@ -679,64 +678,48 @@ yds_init(struct yds_softc *sc)
return 0;
}
-static void
-yds_powerhook(int why, void *addr)
+static bool
+yds_suspend(device_t dv)
{
- struct yds_softc *sc;
- pci_chipset_tag_t pc;
- pcitag_t tag;
- pcireg_t reg;
- int s;
+ struct yds_softc *sc = device_private(dv);
+ pci_chipset_tag_t pc = sc->sc_pc;
+ pcitag_t tag = sc->sc_pcitag;
- sc = (struct yds_softc *)addr;
- pc = sc->sc_pc;
- tag = sc->sc_pcitag;
+ sc->sc_dsctrl = pci_conf_read(pc, tag, YDS_PCI_DSCTRL);
+ sc->sc_legacy = pci_conf_read(pc, tag, YDS_PCI_LEGACY);
+ sc->sc_ba[0] = pci_conf_read(pc, tag, YDS_PCI_FM_BA);
+ sc->sc_ba[1] = pci_conf_read(pc, tag, YDS_PCI_MPU_BA);
- s = splaudio();
- switch (why) {
- case PWR_SUSPEND:
- pci_conf_capture(pc, tag, &sc->sc_pciconf);
+ return true;
+}
- sc->sc_dsctrl = pci_conf_read(pc, tag, YDS_PCI_DSCTRL);
- sc->sc_legacy = pci_conf_read(pc, tag, YDS_PCI_LEGACY);
- sc->sc_ba[0] = pci_conf_read(pc, tag, YDS_PCI_FM_BA);
- sc->sc_ba[1] = pci_conf_read(pc, tag, YDS_PCI_MPU_BA);
- break;
- case PWR_RESUME:
- pci_conf_restore(pc, tag, &sc->sc_pciconf);
-
- /* Disable legacy mode */
- reg = pci_conf_read(pc, tag, YDS_PCI_LEGACY);
- pci_conf_write(pc, tag, YDS_PCI_LEGACY,
- reg & YDS_PCI_LEGACY_LAD);
-
- /* Enable the device. */
- reg = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
- reg |= (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
- PCI_COMMAND_MASTER_ENABLE);
- pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, reg);
- reg = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
- if (yds_init(sc)) {
- printf("%s: reinitialize failed\n",
- sc->sc_dev.dv_xname);
- splx(s);
- return;
- }
- pci_conf_write(pc, tag, YDS_PCI_DSCTRL, sc->sc_dsctrl);
- sc->sc_codec[0].codec_if->vtbl->restore_ports(sc->sc_codec[0].codec_if);
- break;
- case PWR_SOFTRESUME:
- pci_conf_write(pc, tag, YDS_PCI_LEGACY, sc->sc_legacy);
- pci_conf_write(pc, tag, YDS_PCI_FM_BA, sc->sc_ba[0]);
- pci_conf_write(pc, tag, YDS_PCI_MPU_BA, sc->sc_ba[1]);
-#if notyet
- yds_configure_legacy(addr);
-#endif
- break;
+static bool
+yds_resume(device_t dv)
+{
+ struct yds_softc *sc = device_private(dv);
+ pci_chipset_tag_t pc = sc->sc_pc;
+ pcitag_t tag = sc->sc_pcitag;
+ pcireg_t reg;
+
+ /* Disable legacy mode */
+ reg = pci_conf_read(pc, tag, YDS_PCI_LEGACY);
+ pci_conf_write(pc, tag, YDS_PCI_LEGACY, reg & YDS_PCI_LEGACY_LAD);
+
+ /* Enable the device. */
+ reg = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
+ reg |= (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
+ PCI_COMMAND_MASTER_ENABLE);
+ pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, reg);
+ reg = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
+ if (yds_init(sc)) {
+ aprint_error_dev(dv, "reinitialize failed\n");
+ return false;
}
- splx(s);
- return;
+ pci_conf_write(pc, tag, YDS_PCI_DSCTRL, sc->sc_dsctrl);
+ sc->sc_codec[0].codec_if->vtbl->restore_ports(sc->sc_codec[0].codec_if);
+
+ return true;
}
static void
@@ -929,7 +912,8 @@ detected:
sc->sc_legacy_iot = pa->pa_iot;
config_defer((struct device*) sc, yds_configure_legacy);
- powerhook_establish(sc->sc_dev.dv_xname, yds_powerhook, sc);
+ if (!pmf_device_register(self, yds_suspend, yds_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
diff --git a/sys/dev/pckbport/pckbd.c b/sys/dev/pckbport/pckbd.c
index 46ab38c12d4..5ccccc32739 100644
--- a/sys/dev/pckbport/pckbd.c
+++ b/sys/dev/pckbport/pckbd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pckbd.c,v 1.17 2007/12/01 14:36:15 jmcneill Exp $ */
+/* $NetBSD: pckbd.c,v 1.18 2007/12/09 20:28:13 jmcneill Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -75,7 +75,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pckbd.c,v 1.17 2007/12/01 14:36:15 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pckbd.c,v 1.18 2007/12/09 20:28:13 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -126,12 +126,9 @@ struct pckbd_softc {
#ifdef WSDISPLAY_COMPAT_RAWKBD
int rawkbd;
#endif
-
- void *sc_powerhook;
};
static int pckbd_is_console(pckbport_tag_t, pckbport_slot_t);
-static void pckbd_powerhook(int, void *);
int pckbdprobe(struct device *, struct cfdata *, void *);
void pckbdattach(struct device *, struct device *, void *);
@@ -249,55 +246,55 @@ pckbd_is_console(pckbport_tag_t tag, pckbport_slot_t slot)
tag == pckbd_consdata.t_kbctag && slot == pckbd_consdata.t_kbcslot;
}
-static void
-pckbd_powerhook(int why, void *opaque)
+static bool
+pckbd_suspend(device_t dv)
{
- struct pckbd_softc *sc;
+ struct pckbd_softc *sc = device_private(dv);
+ u_char cmd[1];
int res;
- u_char cmd[1], resp[1];
- sc = (struct pckbd_softc *)opaque;
+ /* XXX duped from pckbd_enable, but we want to disable
+ * it even if it's the console kbd
+ */
+ cmd[0] = KBC_DISABLE;
+ res = pckbport_enqueue_cmd(sc->id->t_kbctag,
+ sc->id->t_kbcslot, cmd, 1, 0, 1, 0);
+ if (res)
+ return false;
- switch (why) {
- case PWR_STANDBY:
- case PWR_SUSPEND:
- printf("%s: suspending...\n", sc->sc_dev.dv_xname);
- /* XXX duped from pckbd_enable, but we want to disable it
- * even if it's the console kbd
- */
- cmd[0] = KBC_DISABLE;
- res = pckbport_enqueue_cmd(sc->id->t_kbctag, sc->id->t_kbcslot,
- cmd, 1, 0, 1, 0);
- if (res)
- printf("pckbd_disable: command error\n");
+ pckbport_slot_enable(sc->id->t_kbctag,
+ sc->id->t_kbcslot, 0);
- pckbport_slot_enable(sc->id->t_kbctag, sc->id->t_kbcslot, 0);
+ sc->sc_enabled = 0;
+ return true;
+}
- sc->sc_enabled = 0;
- break;
- case PWR_RESUME:
- printf("%s: resuming...\n", sc->sc_dev.dv_xname);
+static bool
+pckbd_resume(device_t dv)
+{
+ struct pckbd_softc *sc = device_private(dv);
+ u_char cmd[1], resp[1];
+ int res;
- /* XXX jmcneill reset the keyboard */
- cmd[0] = KBC_RESET;
- res = pckbport_poll_cmd(sc->id->t_kbctag, sc->id->t_kbcslot,
- cmd, 1, 1, resp, 1);
+ /* XXX jmcneill reset the keyboard */
+ pckbport_flush(sc->id->t_kbctag, sc->id->t_kbcslot);
+
+ cmd[0] = KBC_RESET;
+ res = pckbport_poll_cmd(sc->id->t_kbctag,
+ sc->id->t_kbcslot, cmd, 1, 1, resp, 1);
#ifdef DEBUG
- if (res)
- printf("pckbdprobe: reset error %d\n", res);
+ if (res)
+ printf("pckbdprobe: reset error %d\n", res);
#endif
- if (resp[0] != KBR_RSTDONE)
- printf("pckbdprobe: reset response 0x%x\n", resp[0]);
-
- pckbport_flush(sc->id->t_kbctag, sc->id->t_kbcslot);
+ if (resp[0] != KBR_RSTDONE)
+ printf("pckbdprobe: reset response 0x%x\n",
+ resp[0]);
- pckbd_set_xtscancode(sc->id->t_kbctag, sc->id->t_kbcslot);
+ pckbport_flush(sc->id->t_kbctag, sc->id->t_kbcslot);
- pckbd_enable(sc, 1);
- break;
- }
+ pckbd_enable(sc, 1);
- return;
+ return true;
}
/*
@@ -404,11 +401,8 @@ pckbdattach(struct device *parent, struct device *self, void *aux)
a.accessops = &pckbd_accessops;
a.accesscookie = sc;
- sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- pckbd_powerhook, sc);
- if (sc->sc_powerhook == NULL)
- aprint_error("%s: unable to install powerhook\n",
- sc->sc_dev.dv_xname);
+ if (!pmf_device_register(self, pckbd_suspend, pckbd_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
/*
* Attach the wskbd, saving a handle to it.
diff --git a/sys/dev/pckbport/pms.c b/sys/dev/pckbport/pms.c
index 12b25da6e58..8dfaeb952b8 100644
--- a/sys/dev/pckbport/pms.c
+++ b/sys/dev/pckbport/pms.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pms.c,v 1.21 2007/12/01 14:36:15 jmcneill Exp $ */
+/* $NetBSD: pms.c,v 1.22 2007/12/09 20:28:13 jmcneill Exp $ */
/*-
* Copyright (c) 2004 Kentaro Kurahone.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pms.c,v 1.21 2007/12/01 14:36:15 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pms.c,v 1.22 2007/12/09 20:28:13 jmcneill Exp $");
#include "opt_pms.h"
@@ -85,9 +85,9 @@ static void pms_reset_thread(void*);
int pms_enable(void *);
int pms_ioctl(void *, u_long, void *, int, struct lwp *);
void pms_disable(void *);
-#ifndef PMS_DISABLE_POWERHOOK
-void pms_power(int, void *);
-#endif /* !PMS_DISABLE_POWERHOOK */
+
+static bool pms_suspend(device_t);
+static bool pms_resume(device_t);
const struct wsmouse_accessops pms_accessops = {
pms_enable,
@@ -230,9 +230,10 @@ pmsattach(struct device *parent, struct device *self, void *aux)
&sc->sc_event_thread, sc->sc_dev.dv_xname);
#ifndef PMS_DISABLE_POWERHOOK
- sc->sc_powerhook = powerhook_establish(self->dv_xname, pms_power, sc);
sc->sc_suspended = 0;
-#endif /* !PMS_DISABLE_POWERHOOK */
+#endif
+ if (!pmf_device_register(self, pms_suspend, pms_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static void
@@ -334,43 +335,36 @@ pms_disable(void *v)
splx(s);
}
-#ifndef PMS_DISABLE_POWERHOOK
-void
-pms_power(int why, void *v)
+static bool
+pms_suspend(device_t dv)
{
- struct pms_softc *sc = v;
+ struct pms_softc *sc = device_private(dv);
+
+ if (sc->sc_enabled)
+ do_disable(sc);
+
+ return true;
+}
+
+static bool
+pms_resume(device_t dv)
+{
+ struct pms_softc *sc = device_private(dv);
- switch (why) {
- case PWR_STANDBY:
- break;
- case PWR_SUSPEND:
- if (sc->sc_enabled) {
- do_disable(sc);
- sc->sc_suspended = 1;
- }
- break;
- case PWR_RESUME:
#ifdef PMS_SYNAPTICS_TOUCHPAD
- if (sc->protocol == PMS_SYNAPTICS) {
- pms_synaptics_resume(sc);
- sc->sc_suspended = 0;
- do_enable(sc);
- }
+ if (sc->protocol == PMS_SYNAPTICS) {
+ pms_synaptics_resume(sc);
+ do_enable(sc);
+ } else
#endif
- if (sc->sc_enabled && sc->sc_suspended) {
- /* recheck protocol & init mouse */
- sc->protocol = PMS_UNKNOWN;
- sc->sc_suspended = 0;
- do_enable(sc); /* only if we were suspended */
- }
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
+ if (sc->sc_enabled) {
+ /* recheck protocol & init mouse */
+ sc->protocol = PMS_UNKNOWN;
+ do_enable(sc); /* only if we were suspended */
}
+
+ return true;
}
-#endif /* !PMS_DISABLE_POWERHOOK */
int
pms_ioctl(void *v, u_long cmd, void *data, int flag,
diff --git a/sys/dev/pckbport/wskbdmap_mfii.c b/sys/dev/pckbport/wskbdmap_mfii.c
index 8a7bcdbfeac..527d797c461 100644
--- a/sys/dev/pckbport/wskbdmap_mfii.c
+++ b/sys/dev/pckbport/wskbdmap_mfii.c
@@ -1,4 +1,4 @@
-/* $NetBSD: wskbdmap_mfii.c,v 1.11 2006/04/01 23:02:32 christos Exp $ */
+/* $NetBSD: wskbdmap_mfii.c,v 1.12 2007/12/09 20:28:13 jmcneill Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wskbdmap_mfii.c,v 1.11 2006/04/01 23:02:32 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wskbdmap_mfii.c,v 1.12 2007/12/09 20:28:13 jmcneill Exp $");
#include <sys/types.h>
#include <dev/wscons/wsksymdef.h>
@@ -136,7 +136,10 @@ static const keysym_t pckbd_keydesc_us[] = {
KC(127), KS_Pause, /* Break */
KC(156), KS_KP_Enter,
KC(157), KS_Control_R,
+ KC(160), KS_Cmd_VolumeToggle,
KC(170), KS_Print_Screen,
+ KC(174), KS_Cmd_VolumeDown,
+ KC(176), KS_Cmd_VolumeUp,
KC(181), KS_KP_Divide,
KC(183), KS_Print_Screen,
KC(184), KS_Alt_R, KS_Multi_key,
diff --git a/sys/dev/pcmcia/if_an_pcmcia.c b/sys/dev/pcmcia/if_an_pcmcia.c
index 2762f9c247c..6ebb53be71e 100644
--- a/sys/dev/pcmcia/if_an_pcmcia.c
+++ b/sys/dev/pcmcia/if_an_pcmcia.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_an_pcmcia.c,v 1.32 2007/10/19 12:01:04 ad Exp $ */
+/* $NetBSD: if_an_pcmcia.c,v 1.33 2007/12/09 20:28:14 jmcneill Exp $ */
/*-
* Copyright (c) 2000, 2004 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_an_pcmcia.c,v 1.32 2007/10/19 12:01:04 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_an_pcmcia.c,v 1.33 2007/12/09 20:28:14 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -84,7 +84,6 @@ struct an_pcmcia_softc {
int sc_io_window; /* our i/o window */
struct pcmcia_function *sc_pf; /* our PCMCIA function */
void *sc_ih; /* interrupt handle */
- void *sc_powerhook; /* power hook descriptor */
int sc_state;
#define AN_PCMCIA_ATTACHED 3
@@ -164,7 +163,10 @@ an_pcmcia_attach(struct device *parent, struct device *self,
goto fail2;
}
- psc->sc_powerhook = powerhook_establish(self->dv_xname, an_power, sc);
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, &sc->sc_if);
an_pcmcia_disable(sc);
sc->sc_enabled = 0;
@@ -188,8 +190,7 @@ an_pcmcia_detach(struct device *self, int flags)
if (psc->sc_state != AN_PCMCIA_ATTACHED)
return (0);
- if (psc->sc_powerhook)
- powerhook_disestablish(psc->sc_powerhook);
+ pmf_device_deregister(self);
error = an_detach(&psc->sc_an);
if (error)
diff --git a/sys/dev/pcmcia/if_ray.c b/sys/dev/pcmcia/if_ray.c
index db6213f6387..4a04394654f 100644
--- a/sys/dev/pcmcia/if_ray.c
+++ b/sys/dev/pcmcia/if_ray.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ray.c,v 1.67 2007/10/19 12:01:05 ad Exp $ */
+/* $NetBSD: if_ray.c,v 1.68 2007/12/09 20:28:14 jmcneill Exp $ */
/*
* Copyright (c) 2000 Christian E. Hopps
@@ -57,7 +57,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ray.c,v 1.67 2007/10/19 12:01:05 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ray.c,v 1.68 2007/12/09 20:28:14 jmcneill Exp $");
#include "opt_inet.h"
#include "bpfilter.h"
@@ -158,12 +158,8 @@ struct ray_softc {
struct pcmcia_function *sc_pf;
void *sc_ih;
- void *sc_sdhook;
- void *sc_pwrhook;
int sc_attached;
- int sc_flags; /*. misc flags */
-#define RAY_FLAGS_RESUMEINIT 0x0001
int sc_resetloop;
struct callout sc_check_ccs_ch;
@@ -302,6 +298,7 @@ static u_int ray_find_free_tx_ccs(struct ray_softc *, u_int);
static u_int8_t ray_free_ccs(struct ray_softc *, bus_size_t);
static void ray_free_ccs_chain(struct ray_softc *, u_int);
static void ray_if_start(struct ifnet *);
+static void ray_if_stop(struct ifnet *, int);
static int ray_init(struct ray_softc *);
static int ray_intr(void *);
static void ray_intr_start(struct ray_softc *);
@@ -310,7 +307,6 @@ static int ray_issue_cmd(struct ray_softc *, bus_size_t, u_int);
static int ray_match(struct device *, struct cfdata *, void *);
static int ray_media_change(struct ifnet *);
static void ray_media_status(struct ifnet *, struct ifmediareq *);
-void ray_power(int, void *);
static ray_cmd_func_t ray_rccs_intr(struct ray_softc *, bus_size_t);
static void ray_read_region(struct ray_softc *, bus_size_t,void *,size_t);
static void ray_recv(struct ray_softc *, bus_size_t);
@@ -320,7 +316,6 @@ static void ray_reset(struct ray_softc *);
static void ray_reset_resetloop(void *);
static int ray_send_auth(struct ray_softc *, u_int8_t *, u_int8_t);
static void ray_set_pending(struct ray_softc *, u_int);
-static void ray_shutdown(void *);
static int ray_simple_cmd(struct ray_softc *, u_int, u_int);
static void ray_start_assoc(struct ray_softc *);
static void ray_start_join_net(struct ray_softc *);
@@ -571,7 +566,6 @@ ray_attach(struct device *parent, struct device *self, void *aux)
sc->sc_omode = sc->sc_mode = RAY_MODE_DEFAULT;
sc->sc_countrycode = sc->sc_dcountrycode =
RAY_PID_COUNTRY_CODE_DEFAULT;
- sc->sc_flags &= ~RAY_FLAGS_RESUMEINIT;
/*
* attach the interface
@@ -590,6 +584,7 @@ ray_attach(struct device *parent, struct device *self, void *aux)
memcpy(ifp->if_xname, self->dv_xname, IFNAMSIZ);
ifp->if_softc = sc;
ifp->if_start = ray_if_start;
+ ifp->if_stop = ray_if_stop;
ifp->if_ioctl = ray_ioctl;
ifp->if_mtu = ETHERMTU;
ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST;
@@ -609,8 +604,10 @@ ray_attach(struct device *parent, struct device *self, void *aux)
else
ifmedia_set(&sc->sc_media, IFM_INFRA);
- sc->sc_sdhook = shutdownhook_establish(ray_shutdown, sc);
- sc->sc_pwrhook = powerhook_establish(self->dv_xname, ray_power, sc);
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, ifp);
/* The attach is successful. */
sc->sc_attached = 1;
@@ -655,17 +652,14 @@ ray_detach(struct device *self, int flags)
struct ray_softc *sc;
struct ifnet *ifp;
- sc = (struct ray_softc *)self;
+ sc = device_private(self);
ifp = &sc->sc_if;
RAY_DPRINTF(("%s: detach\n", sc->sc_xname));
if (!sc->sc_attached)
return (0);
- if (sc->sc_pwrhook)
- powerhook_disestablish(sc->sc_pwrhook);
- if (sc->sc_sdhook)
- shutdownhook_disestablish(sc->sc_sdhook);
+ pmf_device_deregister(self);
if (sc->sc_if.if_flags & IFF_UP)
ray_disable(sc);
@@ -760,7 +754,6 @@ ray_init(sc)
sc->sc_running = 0;
sc->sc_txfree = RAY_CCS_NTX;
sc->sc_checkcounters = 0;
- sc->sc_flags &= ~RAY_FLAGS_RESUMEINIT;
sc->sc_authstate = RAY_AUTH_UNAUTH;
/* get startup results */
@@ -878,42 +871,6 @@ ray_reset_resetloop(arg)
sc->sc_resetloop = 0;
}
-void
-ray_power(int why, void *arg)
-{
-#if 0
- struct ray_softc *sc;
-
- /* can't do this until power hooks are called from thread */
- sc = arg;
- switch (why) {
- case PWR_RESUME:
- if ((sc->sc_flags & RAY_FLAGS_RESUMEINIT))
- ray_init(sc);
- break;
- case PWR_SUSPEND:
- if ((sc->sc_if.if_flags & IFF_RUNNING)) {
- ray_stop(sc);
- sc->sc_flags |= RAY_FLAGS_RESUMEINIT;
- }
- break;
- case PWR_STANDBY:
- default:
- break;
- }
-#endif
-}
-
-static void
-ray_shutdown(arg)
- void *arg;
-{
- struct ray_softc *sc;
-
- sc = arg;
- ray_disable(sc);
-}
-
static int
ray_ioctl(ifp, cmd, data)
struct ifnet *ifp;
@@ -1070,6 +1027,14 @@ ray_if_start(ifp)
ray_intr_start(sc);
}
+static void
+ray_if_stop(struct ifnet *ifp, int disable)
+{
+ struct ray_softc *sc = ifp->if_softc;
+
+ ray_stop(sc);
+}
+
static int
ray_media_change(ifp)
struct ifnet *ifp;
diff --git a/sys/dev/pcmcia/if_wi_pcmcia.c b/sys/dev/pcmcia/if_wi_pcmcia.c
index 769621aa38f..609c02df62d 100644
--- a/sys/dev/pcmcia/if_wi_pcmcia.c
+++ b/sys/dev/pcmcia/if_wi_pcmcia.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wi_pcmcia.c,v 1.76 2007/10/19 12:01:05 ad Exp $ */
+/* $NetBSD: if_wi_pcmcia.c,v 1.77 2007/12/09 20:28:14 jmcneill Exp $ */
/*-
* Copyright (c) 2001, 2004 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wi_pcmcia.c,v 1.76 2007/10/19 12:01:05 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wi_pcmcia.c,v 1.77 2007/12/09 20:28:14 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -87,8 +87,6 @@ static void wi_pcmcia_attach(struct device *, struct device *, void *);
static int wi_pcmcia_detach(struct device *, int);
static int wi_pcmcia_enable(struct wi_softc *);
static void wi_pcmcia_disable(struct wi_softc *);
-static void wi_pcmcia_powerhook(int, void *);
-static void wi_pcmcia_shutdown(void *);
#if WI_PCMCIA_SPECTRUM24T_FW
/* support to download firmware for symbol CF card */
@@ -100,8 +98,6 @@ static int wi_pcmcia_set_hcr(struct wi_softc *, int);
struct wi_pcmcia_softc {
struct wi_softc sc_wi;
- void *sc_powerhook; /* power hook descriptor */
- void *sc_sdhook; /* shutdown hook */
int sc_symbol_cf; /* Spectrum24t CF card */
struct pcmcia_function *sc_pf; /* PCMCIA function */
@@ -392,9 +388,10 @@ wi_pcmcia_attach(struct device *parent, struct device *self,
goto fail2;
}
- psc->sc_sdhook = shutdownhook_establish(wi_pcmcia_shutdown, psc);
- psc->sc_powerhook = powerhook_establish(self->dv_xname,
- wi_pcmcia_powerhook, psc);
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else
+ pmf_class_network_register(self, &sc->sc_if);
wi_pcmcia_disable(sc);
psc->sc_state = WI_PCMCIA_ATTACHED;
@@ -415,11 +412,6 @@ wi_pcmcia_detach(struct device *self, int flags)
if (psc->sc_state != WI_PCMCIA_ATTACHED)
return (0);
- if (psc->sc_powerhook)
- powerhook_disestablish(psc->sc_powerhook);
- if (psc->sc_sdhook)
- shutdownhook_disestablish(psc->sc_sdhook);
-
error = wi_detach(&psc->sc_wi);
if (error != 0)
return (error);
@@ -429,27 +421,6 @@ wi_pcmcia_detach(struct device *self, int flags)
return (0);
}
-static void
-wi_pcmcia_powerhook(why, arg)
- int why;
- void *arg;
-{
- struct wi_pcmcia_softc *psc = arg;
- struct wi_softc *sc = &psc->sc_wi;
-
- wi_power(sc, why);
-}
-
-static void
-wi_pcmcia_shutdown(arg)
- void *arg;
-{
- struct wi_pcmcia_softc *psc = arg;
- struct wi_softc *sc = &psc->sc_wi;
-
- wi_shutdown(sc);
-}
-
/*
* Special routines to download firmware for Symbol CF card.
* XXX: This should be modified generic into any PRISM-2 based card.
diff --git a/sys/dev/pcmcia/pcmcia.c b/sys/dev/pcmcia/pcmcia.c
index 67d579624d5..059fe6f69d2 100644
--- a/sys/dev/pcmcia/pcmcia.c
+++ b/sys/dev/pcmcia/pcmcia.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pcmcia.c,v 1.83 2007/12/01 14:36:57 jmcneill Exp $ */
+/* $NetBSD: pcmcia.c,v 1.84 2007/12/09 20:28:14 jmcneill Exp $ */
/*
* Copyright (c) 2004 Charles M. Hannum. All rights reserved.
@@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pcmcia.c,v 1.83 2007/12/01 14:36:57 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pcmcia.c,v 1.84 2007/12/09 20:28:14 jmcneill Exp $");
#include "opt_pcmciaverbose.h"
@@ -56,6 +56,8 @@ __KERNEL_RCSID(0, "$NetBSD: pcmcia.c,v 1.83 2007/12/01 14:36:57 jmcneill Exp $")
#include <sys/systm.h>
#include <sys/device.h>
+#include <net/if.h>
+
#include <dev/pcmcia/pcmciareg.h>
#include <dev/pcmcia/pcmciachip.h>
#include <dev/pcmcia/pcmciavar.h>
@@ -138,6 +140,9 @@ pcmcia_attach(struct device *parent, struct device *self, void *aux)
sc->iosize = paa->iosize;
sc->ih = NULL;
+
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
int
diff --git a/sys/dev/rasops/rasops.c b/sys/dev/rasops/rasops.c
index 5008b4beb37..1cd1961927b 100644
--- a/sys/dev/rasops/rasops.c
+++ b/sys/dev/rasops/rasops.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rasops.c,v 1.56 2007/07/28 20:28:57 mjf Exp $ */
+/* $NetBSD: rasops.c,v 1.57 2007/12/09 20:28:14 jmcneill Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rasops.c,v 1.56 2007/07/28 20:28:57 mjf Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rasops.c,v 1.57 2007/12/09 20:28:14 jmcneill Exp $");
#include "opt_rasops.h"
#include "rasops_glue.h"
@@ -945,8 +945,10 @@ rasops_do_cursor(ri)
*(int32_t *)dp ^= ~0;
dp += 4;
if (ri->ri_hwbits) {
- *(int32_t *)hp ^= ~0;
+ dp -= 4;
+ *(int32_t *)hp = *(int32_t *)dp;
hp += 4;
+ dp += 4;
}
}
}
@@ -962,16 +964,19 @@ rasops_do_cursor(ri)
if (slop1 & 1) {
*dp++ ^= ~0;
- if (ri->ri_hwbits)
- *hp++ ^= ~0;
+ if (ri->ri_hwbits) {
+ *hp++ = *(dp - 1);
+ }
}
if (slop1 & 2) {
*(int16_t *)dp ^= ~0;
dp += 2;
if (ri->ri_hwbits) {
- *(int16_t *)hp ^= ~0;
+ dp -= 2;
+ *(int16_t *)hp = *(int16_t *)dp;
hp += 2;
+ dp += 2;
}
}
@@ -979,21 +984,23 @@ rasops_do_cursor(ri)
*(int32_t *)dp ^= ~0;
dp += 4;
if (ri->ri_hwbits) {
- *(int32_t *)hp ^= ~0;
+ dp -= 4;
+ *(int32_t *)hp = *(int32_t *)dp;
hp += 4;
+ dp += 4;
}
}
if (slop2 & 1) {
*dp++ ^= ~0;
if (ri->ri_hwbits)
- *hp++ ^= ~0;
+ *hp++ = *(dp - 1);
}
if (slop2 & 2) {
*(int16_t *)dp ^= ~0;
if (ri->ri_hwbits)
- *(int16_t *)hp ^= ~0;
+ *(int16_t *)hp = *(int16_t *)(dp - 2);
}
}
}
diff --git a/sys/dev/rasops/rasops8.c b/sys/dev/rasops/rasops8.c
index 1fe5f08d4ec..f5d01a1e375 100644
--- a/sys/dev/rasops/rasops8.c
+++ b/sys/dev/rasops/rasops8.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rasops8.c,v 1.22 2007/03/04 06:02:39 christos Exp $ */
+/* $NetBSD: rasops8.c,v 1.23 2007/12/09 20:28:14 jmcneill Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rasops8.c,v 1.22 2007/03/04 06:02:39 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rasops8.c,v 1.23 2007/12/09 20:28:14 jmcneill Exp $");
#include "opt_rasops.h"
@@ -289,7 +289,8 @@ rasops8_putchar8(cookie, row, col, uc, attr)
rp[0] = rp[1] = stamp[0];
DELTA(rp, ri->ri_stride, int32_t *);
if (ri->ri_hwbits) {
- hp[0] = hp[1] = stamp[0];
+ hp[0] = stamp[0];
+ hp[1] = stamp[0];
DELTA(hp, ri->ri_stride, int32_t *);
}
}
@@ -321,7 +322,8 @@ rasops8_putchar8(cookie, row, col, uc, attr)
rp[0] = rp[1] = stamp[15];
if (ri->ri_hwbits) {
DELTA(hp, -(ri->ri_stride << 1), int32_t *);
- hp[0] = hp[1] = stamp[15];
+ hp[0] = stamp[15];
+ hp[1] = stamp[15];
}
}
@@ -385,7 +387,9 @@ rasops8_putchar12(cookie, row, col, uc, attr)
rp[0] = rp[1] = rp[2] = c;
DELTA(rp, ri->ri_stride, int32_t *);
if (ri->ri_hwbits) {
- hrp[0] = hrp[1] = hrp[2] = c;
+ hrp[0] = c;
+ hrp[1] = c;
+ hrp[2] = c;
DELTA(hrp, ri->ri_stride, int32_t *);
}
}
@@ -417,7 +421,9 @@ rasops8_putchar12(cookie, row, col, uc, attr)
rp[0] = rp[1] = rp[2] = stamp[15];
if (ri->ri_hwbits) {
DELTA(hrp, -(ri->ri_stride << 1), int32_t *);
- hrp[0] = hrp[1] = hrp[2] = stamp[15];
+ hrp[0] = stamp[15];
+ hrp[1] = stamp[15];
+ hrp[2] = stamp[15];
}
}
@@ -478,8 +484,12 @@ rasops8_putchar16(cookie, row, col, uc, attr)
if (uc == ' ') {
while (height--) {
rp[0] = rp[1] = rp[2] = rp[3] = stamp[0];
- if (ri->ri_hwbits)
- hrp[0] = hrp[1] = hrp[2] = hrp[3] = stamp[0];
+ if (ri->ri_hwbits) {
+ hrp[0] = stamp[0];
+ hrp[1] = stamp[0];
+ hrp[2] = stamp[0];
+ hrp[3] = stamp[0];
+ }
}
} else {
uc -= ri->ri_font->firstchar;
@@ -511,7 +521,10 @@ rasops8_putchar16(cookie, row, col, uc, attr)
rp[0] = rp[1] = rp[2] = rp[3] = stamp[15];
if (ri->ri_hwbits) {
DELTA(hrp, -(ri->ri_stride << 1), int32_t *);
- hrp[0] = hrp[1] = hrp[2] = hrp[3] = stamp[15];
+ hrp[0] = stamp[15];
+ hrp[1] = stamp[15];
+ hrp[2] = stamp[15];
+ hrp[3] = stamp[15];
}
}
diff --git a/sys/dev/scsipi/atapiconf.c b/sys/dev/scsipi/atapiconf.c
index 8e85012215f..21bbd59d3bf 100644
--- a/sys/dev/scsipi/atapiconf.c
+++ b/sys/dev/scsipi/atapiconf.c
@@ -1,4 +1,4 @@
-/* $NetBSD: atapiconf.c,v 1.73 2007/12/01 14:46:04 jmcneill Exp $ */
+/* $NetBSD: atapiconf.c,v 1.74 2007/12/09 20:28:22 jmcneill Exp $ */
/*
* Copyright (c) 1996, 2001 Manuel Bouyer. All rights reserved.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: atapiconf.c,v 1.73 2007/12/01 14:46:04 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: atapiconf.c,v 1.74 2007/12/09 20:28:22 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -162,6 +162,9 @@ atapibusattach(struct device *parent, struct device *self, void *aux)
chan->chan_init_cb_arg = NULL;
scsipi_channel_init(chan);
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
/* Probe the bus for devices. */
atapi_probe_bus(sc, -1);
}
diff --git a/sys/dev/scsipi/cd.c b/sys/dev/scsipi/cd.c
index dc5dfa379f7..7f0f12731df 100644
--- a/sys/dev/scsipi/cd.c
+++ b/sys/dev/scsipi/cd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cd.c,v 1.270 2007/11/27 18:06:37 reinoud Exp $ */
+/* $NetBSD: cd.c,v 1.271 2007/12/09 20:28:22 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 2001, 2003, 2004, 2005 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.270 2007/11/27 18:06:37 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.271 2007/12/09 20:28:22 jmcneill Exp $");
#include "rnd.h"
@@ -289,6 +289,9 @@ cdattach(struct device *parent, struct device *self, void *aux)
rnd_attach_source(&cd->rnd_source, cd->sc_dev.dv_xname,
RND_TYPE_DISK, 0);
#endif
+
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
static int
@@ -3485,4 +3488,3 @@ mmc_gettrackinfo(struct scsipi_periph *periph,
return 0;
}
-
diff --git a/sys/dev/scsipi/scsiconf.c b/sys/dev/scsipi/scsiconf.c
index 21057d8d322..4b36b440f6a 100644
--- a/sys/dev/scsipi/scsiconf.c
+++ b/sys/dev/scsipi/scsiconf.c
@@ -1,4 +1,4 @@
-/* $NetBSD: scsiconf.c,v 1.243 2007/03/04 06:02:42 christos Exp $ */
+/* $NetBSD: scsiconf.c,v 1.244 2007/12/09 20:28:22 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 1999, 2004 The NetBSD Foundation, Inc.
@@ -55,7 +55,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: scsiconf.c,v 1.243 2007/03/04 06:02:42 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: scsiconf.c,v 1.244 2007/12/09 20:28:22 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -166,6 +166,9 @@ scsibusattach(struct device *parent, struct device *self, void *aux)
struct scsipi_channel *chan = aux;
struct scsi_initq *scsi_initq;
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
sc->sc_channel = chan;
chan->chan_name = sc->sc_dev.dv_xname;
@@ -285,6 +288,7 @@ scsibusdetach(struct device *self, int flags)
struct scsipi_xfer *xs;
int error;
+ pmf_device_deregister(self);
/*
* Process outstanding commands (which will never complete as the
diff --git a/sys/dev/scsipi/sd.c b/sys/dev/scsipi/sd.c
index 252f1c42c45..31ca48e508d 100644
--- a/sys/dev/scsipi/sd.c
+++ b/sys/dev/scsipi/sd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sd.c,v 1.267 2007/10/08 16:41:14 ad Exp $ */
+/* $NetBSD: sd.c,v 1.268 2007/12/09 20:28:23 jmcneill Exp $ */
/*-
* Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc.
@@ -54,7 +54,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.267 2007/10/08 16:41:14 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.268 2007/12/09 20:28:23 jmcneill Exp $");
#include "opt_scsi.h"
#include "rnd.h"
@@ -107,7 +107,7 @@ static int sdgetdisklabel(struct sd_softc *);
static void sdstart(struct scsipi_periph *);
static void sdrestart(void *);
static void sddone(struct scsipi_xfer *, int);
-static void sd_shutdown(void *);
+static bool sd_suspend(device_t);
static int sd_interpret_sense(struct scsipi_xfer *);
static int sd_mode_sense(struct sd_softc *, u_int8_t, void *, size_t, int,
@@ -306,18 +306,8 @@ sdattach(struct device *parent, struct device *self, void *aux)
}
aprint_normal("\n");
- /*
- * Establish a shutdown hook so that we can ensure that
- * our data has actually made it onto the platter at
- * shutdown time. Note that this relies on the fact
- * that the shutdown hook code puts us at the head of
- * the list (thus guaranteeing that our hook runs before
- * our ancestors').
- */
- if ((sd->sc_sdhook =
- shutdownhook_establish(sd_shutdown, sd)) == NULL)
- aprint_error("%s: WARNING: unable to establish shutdown hook\n",
- sd->sc_dev.dv_xname);
+ if (!pmf_device_register(self, sd_suspend, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
#if NRND > 0
/*
@@ -391,8 +381,7 @@ sddetach(struct device *self, int flags)
disk_detach(&sd->sc_dk);
disk_destroy(&sd->sc_dk);
- /* Get rid of the shutdown hook. */
- shutdownhook_disestablish(sd->sc_sdhook);
+ pmf_device_deregister(self);
#if NRND > 0
/* Unhook the entropy source. */
@@ -1324,10 +1313,10 @@ sdgetdisklabel(struct sd_softc *sd)
return 0;
}
-static void
-sd_shutdown(void *arg)
+static bool
+sd_suspend(device_t dv)
{
- struct sd_softc *sd = arg;
+ struct sd_softc *sd = device_private(dv);
/*
* If the disk cache needs to be flushed, and the disk supports
@@ -1342,6 +1331,8 @@ sd_shutdown(void *arg)
} else
sd->flags &= ~(SDF_FLUSHING|SDF_DIRTY);
}
+
+ return true;
}
/*
diff --git a/sys/dev/sysmon/sysmon_power.c b/sys/dev/sysmon/sysmon_power.c
index e975082a0a7..d75539bc6dc 100644
--- a/sys/dev/sysmon/sysmon_power.c
+++ b/sys/dev/sysmon/sysmon_power.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sysmon_power.c,v 1.32 2007/12/05 17:19:54 pooka Exp $ */
+/* $NetBSD: sysmon_power.c,v 1.33 2007/12/09 20:28:23 jmcneill Exp $ */
/*-
* Copyright (c) 2007 Juan Romero Pardines.
@@ -69,7 +69,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sysmon_power.c,v 1.32 2007/12/05 17:19:54 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysmon_power.c,v 1.33 2007/12/09 20:28:23 jmcneill Exp $");
#include "opt_compat_netbsd.h"
#include <sys/param.h>
@@ -896,6 +896,23 @@ sysmon_pswitch_event(struct sysmon_pswitch *smpsw, int event)
KASSERT(smpsw != NULL);
+ /*
+ * For pnp specific events, we don't care if the power daemon
+ * is running or not
+ */
+ if (smpsw->smpsw_type == PSWITCH_TYPE_LID) {
+ switch (event) {
+ case PSWITCH_EVENT_PRESSED:
+ pmf_event_inject(NULL, PMFE_CHASSIS_LID_CLOSE);
+ break;
+ case PSWITCH_EVENT_RELEASED:
+ pmf_event_inject(NULL, PMFE_CHASSIS_LID_OPEN);
+ break;
+ default:
+ break;
+ }
+ }
+
if (sysmon_power_daemon != NULL) {
/*
* Create a new dictionary for the event.
diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c
index 48b248bc268..5fd95361483 100644
--- a/sys/dev/usb/ehci.c
+++ b/sys/dev/usb/ehci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ehci.c,v 1.126 2007/12/05 07:15:53 ad Exp $ */
+/* $NetBSD: ehci.c,v 1.127 2007/12/09 20:28:23 jmcneill Exp $ */
/*
* Copyright (c) 2004,2005 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.126 2007/12/05 07:15:53 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.127 2007/12/09 20:28:23 jmcneill Exp $");
#include "ohci.h"
#include "uhci.h"
@@ -129,7 +129,6 @@ struct ehci_pipe {
};
Static void ehci_shutdown(void *);
-Static void ehci_power(int, void *);
Static usbd_status ehci_open(usbd_pipe_handle);
Static void ehci_poll(struct usbd_bus *);
@@ -416,8 +415,6 @@ ehci_init(ehci_softc_t *sc)
sc->sc_bus.methods = &ehci_bus_methods;
sc->sc_bus.pipe_size = sizeof(struct ehci_pipe);
- sc->sc_powerhook = powerhook_establish(USBDEVNAME(sc->sc_bus.bdev),
- ehci_power, sc);
sc->sc_shutdownhook = shutdownhook_establish(ehci_shutdown, sc);
sc->sc_eintrs = EHCI_NORMAL_INTRS;
@@ -539,7 +536,7 @@ ehci_intr(void *v)
{
ehci_softc_t *sc = v;
- if (sc == NULL || sc->sc_dying)
+ if (sc == NULL || sc->sc_dying || !device_has_power(&sc->sc_bus.bdev))
return (0);
/* If we get an interrupt while polling, then just ignore it. */
@@ -925,8 +922,6 @@ ehci_detach(struct ehci_softc *sc, int flags)
usb_uncallout(sc->sc_tmo_intrlist, ehci_intrlist_timeout, sc);
- if (sc->sc_powerhook != NULL)
- powerhook_disestablish(sc->sc_powerhook);
if (sc->sc_shutdownhook != NULL)
shutdownhook_disestablish(sc->sc_shutdownhook);
@@ -964,102 +959,122 @@ ehci_activate(device_ptr_t self, enum devact act)
* We need to switch to polling mode here, because this routine is
* called from an interrupt context. This is all right since we
* are almost suspended anyway.
+ *
+ * Note that this power handler isn't to be registered directly; the
+ * bus glue needs to call out to it.
*/
-void
-ehci_power(int why, void *v)
+bool
+ehci_suspend(device_t dv)
{
- ehci_softc_t *sc = v;
- u_int32_t cmd, hcr;
- int s, i;
-
-#ifdef EHCI_DEBUG
- DPRINTF(("ehci_power: sc=%p, why=%d\n", sc, why));
- if (ehcidebug > 0)
- ehci_dump_regs(sc);
-#endif
+ ehci_softc_t *sc = (ehci_softc_t *)dv;
+ int i, s;
+ uint32_t cmd, hcr;
s = splhardusb();
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- sc->sc_bus.use_polling++;
- sc->sc_cmd = EOREAD4(sc, EHCI_USBCMD);
+ sc->sc_bus.use_polling++;
- cmd = sc->sc_cmd & ~(EHCI_CMD_ASE | EHCI_CMD_PSE);
- EOWRITE4(sc, EHCI_USBCMD, cmd);
+ for (i = 1; i <= sc->sc_noport; i++) {
+ cmd = EOREAD4(sc, EHCI_PORTSC(i));
+ if ((cmd & EHCI_PS_PO) == 0 && (cmd & EHCI_PS_PE) == EHCI_PS_PE)
+ EOWRITE4(sc, EHCI_PORTSC(i), cmd | EHCI_PS_SUSP);
+ }
- for (i = 0; i < 100; i++) {
- hcr = EOREAD4(sc, EHCI_USBSTS) &
- (EHCI_STS_ASS | EHCI_STS_PSS);
- if (hcr == 0)
- break;
+ sc->sc_cmd = EOREAD4(sc, EHCI_USBCMD);
- usb_delay_ms(&sc->sc_bus, 1);
- }
- if (hcr != 0) {
- printf("%s: reset timeout\n",
- USBDEVNAME(sc->sc_bus.bdev));
- }
+ cmd = sc->sc_cmd & ~(EHCI_CMD_ASE | EHCI_CMD_PSE);
+ EOWRITE4(sc, EHCI_USBCMD, cmd);
- cmd &= ~EHCI_CMD_RS;
- EOWRITE4(sc, EHCI_USBCMD, cmd);
+ for (i = 0; i < 100; i++) {
+ hcr = EOREAD4(sc, EHCI_USBSTS) & (EHCI_STS_ASS | EHCI_STS_PSS);
+ if (hcr == 0)
+ break;
- for (i = 0; i < 100; i++) {
- hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
- if (hcr == EHCI_STS_HCH)
- break;
+ usb_delay_ms(&sc->sc_bus, 1);
+ }
+ if (hcr != 0)
+ printf("%s: reset timeout\n", USBDEVNAME(sc->sc_bus.bdev));
- usb_delay_ms(&sc->sc_bus, 1);
- }
- if (hcr != EHCI_STS_HCH) {
- printf("%s: config timeout\n",
- USBDEVNAME(sc->sc_bus.bdev));
- }
+ cmd &= ~EHCI_CMD_RS;
+ EOWRITE4(sc, EHCI_USBCMD, cmd);
- sc->sc_bus.use_polling--;
- break;
+ for (i = 0; i < 100; i++) {
+ hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
+ if (hcr == EHCI_STS_HCH)
+ break;
- case PWR_RESUME:
- sc->sc_bus.use_polling++;
+ usb_delay_ms(&sc->sc_bus, 1);
+ }
+ if (hcr != EHCI_STS_HCH)
+ printf("%s: config timeout\n", USBDEVNAME(sc->sc_bus.bdev));
- /* restore things in case the bios sucks */
- EOWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
- EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0));
- EOWRITE4(sc, EHCI_ASYNCLISTADDR,
- sc->sc_async_head->physaddr | EHCI_LINK_QH);
- EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
+ sc->sc_bus.use_polling--;
+ splx(s);
- EOWRITE4(sc, EHCI_USBCMD, sc->sc_cmd);
+ return true;
+}
- for (i = 0; i < 100; i++) {
- hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
- if (hcr != EHCI_STS_HCH)
- break;
+bool
+ehci_resume(device_t dv)
+{
+ ehci_softc_t *sc = (ehci_softc_t *)dv;
+ int i, s;
+ uint32_t cmd, hcr;
- usb_delay_ms(&sc->sc_bus, 1);
- }
- if (hcr == EHCI_STS_HCH) {
- printf("%s: config timeout\n",
- USBDEVNAME(sc->sc_bus.bdev));
+ s = splhardusb();
+
+ sc->sc_bus.use_polling++;
+
+ /* restore things in case the bios sucks */
+ EOWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
+ EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0));
+ EOWRITE4(sc, EHCI_ASYNCLISTADDR,
+ sc->sc_async_head->physaddr | EHCI_LINK_QH);
+ EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
+
+ EOWRITE4(sc, EHCI_USBCMD, sc->sc_cmd);
+
+ hcr = 0;
+ for (i = 1; i <= sc->sc_noport; i++) {
+ cmd = EOREAD4(sc, EHCI_PORTSC(i));
+ if ((cmd & EHCI_PS_PO) == 0 &&
+ (cmd & EHCI_PS_SUSP) == EHCI_PS_SUSP) {
+ EOWRITE4(sc, EHCI_PORTSC(i), cmd | EHCI_PS_FPR);
+ hcr = 1;
}
+ }
+ if (hcr) {
usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
- sc->sc_bus.use_polling--;
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
+ for (i = 1; i <= sc->sc_noport; i++) {
+ cmd = EOREAD4(sc, EHCI_PORTSC(i));
+ if ((cmd & EHCI_PS_PO) == 0 &&
+ (cmd & EHCI_PS_SUSP) == EHCI_PS_SUSP)
+ EOWRITE4(sc, EHCI_PORTSC(i),
+ cmd & ~EHCI_PS_FPR);
+ }
}
+
+ EOWRITE4(sc, EHCI_USBCMD, sc->sc_cmd);
+
+ for (i = 0; i < 100; i++) {
+ hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
+ if (hcr != EHCI_STS_HCH)
+ break;
+
+ usb_delay_ms(&sc->sc_bus, 1);
+ }
+ if (hcr == EHCI_STS_HCH)
+ printf("%s: config timeout\n", USBDEVNAME(sc->sc_bus.bdev));
+
+ usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
+
+ sc->sc_bus.use_polling--;
+
splx(s);
-#ifdef EHCI_DEBUG
- DPRINTF(("ehci_power: sc=%p\n", sc));
- if (ehcidebug > 0)
- ehci_dump_regs(sc);
-#endif
+ return true;
}
/*
diff --git a/sys/dev/usb/ehcivar.h b/sys/dev/usb/ehcivar.h
index fc80e45bb4e..a88beafbebb 100644
--- a/sys/dev/usb/ehcivar.h
+++ b/sys/dev/usb/ehcivar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: ehcivar.h,v 1.25 2007/12/05 07:15:54 ad Exp $ */
+/* $NetBSD: ehcivar.h,v 1.26 2007/12/09 20:28:23 jmcneill Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -97,7 +97,6 @@ typedef struct ehci_softc {
int sc_id_vendor; /* vendor ID for root hub */
u_int32_t sc_cmd; /* shadow of cmd reg during suspend */
- void *sc_powerhook; /* cookie from power hook */
void *sc_shutdownhook; /* cookie from shutdown hook */
u_int sc_ncomp;
@@ -161,3 +160,5 @@ usbd_status ehci_init(ehci_softc_t *);
int ehci_intr(void *);
int ehci_detach(ehci_softc_t *, int);
int ehci_activate(device_ptr_t, enum devact);
+bool ehci_suspend(device_t dv);
+bool ehci_resume(device_t dv);
diff --git a/sys/dev/usb/if_rum.c b/sys/dev/usb/if_rum.c
index 5cff532ab84..8e46a81f096 100644
--- a/sys/dev/usb/if_rum.c
+++ b/sys/dev/usb/if_rum.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: if_rum.c,v 1.65 2007/09/07 19:05:05 damien Exp $ */
-/* $NetBSD: if_rum.c,v 1.18 2007/11/25 09:30:10 kiyohara Exp $ */
+/* $OpenBSD: if_rum.c,v 1.40 2006/09/18 16:20:20 damien Exp $ */
+/* $NetBSD: if_rum.c,v 1.19 2007/12/09 20:28:23 jmcneill Exp $ */
/*-
* Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini@free.fr>
@@ -24,7 +24,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_rum.c,v 1.18 2007/11/25 09:30:10 kiyohara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_rum.c,v 1.19 2007/12/09 20:28:23 jmcneill Exp $");
#include "bpfilter.h"
diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c
index ffed3e114a0..dcc9fc1bad8 100644
--- a/sys/dev/usb/ohci.c
+++ b/sys/dev/usb/ohci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ohci.c,v 1.184 2007/10/19 12:01:21 ad Exp $ */
+/* $NetBSD: ohci.c,v 1.185 2007/12/09 20:28:23 jmcneill Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
/*
@@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.184 2007/10/19 12:01:21 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.185 2007/12/09 20:28:23 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -137,7 +137,6 @@ Static usbd_status ohci_alloc_std_chain(struct ohci_pipe *,
ohci_soft_td_t *, ohci_soft_td_t **);
Static void ohci_shutdown(void *v);
-Static void ohci_power(int, void *);
Static usbd_status ohci_open(usbd_pipe_handle);
Static void ohci_poll(struct usbd_bus *);
Static void ohci_softintr(void *);
@@ -396,7 +395,6 @@ ohci_detach(struct ohci_softc *sc, int flags)
usb_uncallout(sc->sc_tmo_rhsc, ohci_rhsc_enable, sc);
#if defined(__NetBSD__) || defined(__OpenBSD__)
- powerhook_disestablish(sc->sc_powerhook);
shutdownhook_disestablish(sc->sc_shutdownhook);
#endif
@@ -904,8 +902,6 @@ ohci_init(ohci_softc_t *sc)
#if defined(__NetBSD__) || defined(__OpenBSD__)
sc->sc_control = sc->sc_intre = 0;
- sc->sc_powerhook = powerhook_establish(USBDEVNAME(sc->sc_bus.bdev),
- ohci_power, sc);
sc->sc_shutdownhook = shutdownhook_establish(ohci_shutdown, sc);
#endif
@@ -1017,72 +1013,66 @@ ohci_shutdown(void *v)
OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
}
-/*
- * Handle suspend/resume.
- *
- * We need to switch to polling mode here, because this routine is
- * called from an interupt context. This is all right since we
- * are almost suspended anyway.
- */
-void
-ohci_power(int why, void *v)
+bool
+ohci_resume(device_t dv)
{
- ohci_softc_t *sc = v;
- u_int32_t ctl;
+ ohci_softc_t *sc = device_private(dv);
+ uint32_t ctl;
int s;
-#ifdef OHCI_DEBUG
- DPRINTF(("ohci_power: sc=%p, why=%d\n", sc, why));
- ohci_dumpregs(sc);
-#endif
+ s = splhardusb();
+ sc->sc_bus.use_polling++;
+ /* Some broken BIOSes do not recover these values */
+ OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0));
+ OWRITE4(sc, OHCI_CONTROL_HEAD_ED,
+ sc->sc_ctrl_head->physaddr);
+ OWRITE4(sc, OHCI_BULK_HEAD_ED,
+ sc->sc_bulk_head->physaddr);
+ if (sc->sc_intre)
+ OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_intre &
+ (OHCI_ALL_INTRS | OHCI_MIE));
+ if (sc->sc_control)
+ ctl = sc->sc_control;
+ else
+ ctl = OREAD4(sc, OHCI_CONTROL);
+ ctl |= OHCI_HCFS_RESUME;
+ OWRITE4(sc, OHCI_CONTROL, ctl);
+ usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
+ ctl = (ctl & ~OHCI_HCFS_MASK) | OHCI_HCFS_OPERATIONAL;
+ OWRITE4(sc, OHCI_CONTROL, ctl);
+ usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
+ sc->sc_control = sc->sc_intre = 0;
+ sc->sc_bus.use_polling--;
+
+ return true;
+}
+
+bool
+ohci_suspend(device_t dv)
+{
+ ohci_softc_t *sc = device_private(dv);
+ uint32_t ctl;
+ int s;
s = splhardusb();
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- sc->sc_bus.use_polling++;
- ctl = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK;
- if (sc->sc_control == 0) {
- /*
- * Preserve register values, in case that APM BIOS
- * does not recover them.
- */
- sc->sc_control = ctl;
- sc->sc_intre = OREAD4(sc, OHCI_INTERRUPT_ENABLE);
- }
- ctl |= OHCI_HCFS_SUSPEND;
- OWRITE4(sc, OHCI_CONTROL, ctl);
- usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
- sc->sc_bus.use_polling--;
- break;
- case PWR_RESUME:
- sc->sc_bus.use_polling++;
- /* Some broken BIOSes do not recover these values */
- OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0));
- OWRITE4(sc, OHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr);
- OWRITE4(sc, OHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr);
- if (sc->sc_intre)
- OWRITE4(sc, OHCI_INTERRUPT_ENABLE,
- sc->sc_intre & (OHCI_ALL_INTRS | OHCI_MIE));
- if (sc->sc_control)
- ctl = sc->sc_control;
- else
- ctl = OREAD4(sc, OHCI_CONTROL);
- ctl |= OHCI_HCFS_RESUME;
- OWRITE4(sc, OHCI_CONTROL, ctl);
- usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
- ctl = (ctl & ~OHCI_HCFS_MASK) | OHCI_HCFS_OPERATIONAL;
- OWRITE4(sc, OHCI_CONTROL, ctl);
- usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
- sc->sc_control = sc->sc_intre = 0;
- sc->sc_bus.use_polling--;
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
+ sc->sc_bus.use_polling++;
+ ctl = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK;
+ if (sc->sc_control == 0) {
+ /*
+ * Preserve register values, in case that BIOS
+ * does not recover them.
+ */
+ sc->sc_control = ctl;
+ sc->sc_intre = OREAD4(sc,
+ OHCI_INTERRUPT_ENABLE);
}
+ ctl |= OHCI_HCFS_SUSPEND;
+ OWRITE4(sc, OHCI_CONTROL, ctl);
+ usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
+ sc->sc_bus.use_polling--;
splx(s);
+
+ return true;
}
#ifdef OHCI_DEBUG
@@ -1133,7 +1123,7 @@ ohci_intr(void *p)
{
ohci_softc_t *sc = p;
- if (sc == NULL || sc->sc_dying)
+ if (sc == NULL || sc->sc_dying || !device_has_power(&sc->sc_bus.bdev))
return (0);
/* If we get an interrupt while polling, then just ignore it. */
diff --git a/sys/dev/usb/ohcivar.h b/sys/dev/usb/ohcivar.h
index 7130e24f186..269482fd16b 100644
--- a/sys/dev/usb/ohcivar.h
+++ b/sys/dev/usb/ohcivar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: ohcivar.h,v 1.39 2005/12/27 04:06:45 chs Exp $ */
+/* $NetBSD: ohcivar.h,v 1.40 2007/12/09 20:28:24 jmcneill Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohcivar.h,v 1.13 1999/11/17 22:33:41 n_hibma Exp $ */
/*
@@ -155,3 +155,5 @@ int ohci_intr(void *);
int ohci_detach(ohci_softc_t *, int);
int ohci_activate(device_ptr_t, enum devact);
#endif
+bool ohci_resume(device_t);
+bool ohci_suspend(device_t);
diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c
index 7e9ccb07dc6..6994dae5eae 100644
--- a/sys/dev/usb/ugen.c
+++ b/sys/dev/usb/ugen.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ugen.c,v 1.94 2007/12/05 17:19:55 pooka Exp $ */
+/* $NetBSD: ugen.c,v 1.95 2007/12/09 20:28:24 jmcneill Exp $ */
/*
* Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
@@ -44,7 +44,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.94 2007/12/05 17:19:55 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.95 2007/12/09 20:28:24 jmcneill Exp $");
#include "opt_ugen_bulk_ra_wb.h"
#include "opt_compat_netbsd.h"
@@ -271,6 +271,9 @@ USB_ATTACH(ugen)
usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
USBDEV(sc->sc_dev));
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
USB_ATTACH_SUCCESS_RETURN;
}
diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c
index 5827659be8c..7c039bcd10a 100644
--- a/sys/dev/usb/uhci.c
+++ b/sys/dev/usb/uhci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: uhci.c,v 1.211 2007/10/19 12:01:22 ad Exp $ */
+/* $NetBSD: uhci.c,v 1.212 2007/12/09 20:28:24 jmcneill Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
/*
@@ -49,7 +49,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.211 2007/10/19 12:01:22 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.212 2007/12/09 20:28:24 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -165,8 +165,6 @@ struct uhci_pipe {
Static void uhci_globalreset(uhci_softc_t *);
Static usbd_status uhci_portreset(uhci_softc_t*, int);
Static void uhci_reset(uhci_softc_t *);
-Static void uhci_shutdown(void *v);
-Static void uhci_power(int, void *);
Static usbd_status uhci_run(uhci_softc_t *, int run);
Static uhci_soft_td_t *uhci_alloc_std(uhci_softc_t *);
Static void uhci_free_std(uhci_softc_t *, uhci_soft_td_t *);
@@ -545,13 +543,6 @@ uhci_init(uhci_softc_t *sc)
sc->sc_bus.methods = &uhci_bus_methods;
sc->sc_bus.pipe_size = sizeof(struct uhci_pipe);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- sc->sc_suspend = PWR_RESUME;
- sc->sc_powerhook = powerhook_establish(USBDEVNAME(sc->sc_bus.bdev),
- uhci_power, sc);
- sc->sc_shutdownhook = shutdownhook_establish(uhci_shutdown, sc);
-#endif
-
UHCICMD(sc, UHCI_CMD_MAXP); /* Assume 64 byte packets at frame end */
DPRINTFN(1,("uhci_init: enabling\n"));
@@ -593,11 +584,6 @@ uhci_detach(struct uhci_softc *sc, int flags)
if (rv != 0)
return (rv);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- powerhook_disestablish(sc->sc_powerhook);
- shutdownhook_disestablish(sc->sc_shutdownhook);
-#endif
-
/* Free all xfers associated with this HC. */
for (;;) {
xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
@@ -712,111 +698,88 @@ uhci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
}
/*
- * Shut down the controller when the system is going down.
+ * Handle suspend/resume.
+ *
+ * We need to switch to polling mode here, because this routine is
+ * called from an interrupt context. This is all right since we
+ * are almost suspended anyway.
*/
-void
-uhci_shutdown(void *v)
+bool
+uhci_resume(device_t dv)
{
- uhci_softc_t *sc = v;
+ uhci_softc_t *sc = device_private(dv);
+ int cmd;
int s;
- DPRINTF(("uhci_shutdown: stopping the HC\n"));
-
- /*
- * Use polling mode to prevent the interrupts shutting
- * us down before we shut them down.
- */
s = splhardusb();
+
+ cmd = UREAD2(sc, UHCI_CMD);
sc->sc_bus.use_polling++;
- uhci_run(sc, 0); /* stop the controller */
+ if (cmd & UHCI_CMD_RS)
+ uhci_run(sc, 0);
+
+ /* restore saved state */
+ UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0));
+ UWRITE2(sc, UHCI_FRNUM, sc->sc_saved_frnum);
+ UWRITE1(sc, UHCI_SOF, sc->sc_saved_sof);
+
+ UHCICMD(sc, cmd | UHCI_CMD_FGR); /* force resume */
+ usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
+ UHCICMD(sc, cmd & ~UHCI_CMD_EGSM); /* back to normal */
+ UHCICMD(sc, UHCI_CMD_MAXP);
+ UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE |
+ UHCI_INTR_RIE | UHCI_INTR_IOCE | UHCI_INTR_SPIE);
+ uhci_run(sc, 1); /* and start traffic again */
+ usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
sc->sc_bus.use_polling--;
+ if (sc->sc_intr_xfer != NULL)
+ usb_callout(sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub,
+ sc->sc_intr_xfer);
+#ifdef UHCI_DEBUG
+ if (uhcidebug > 2)
+ uhci_dumpregs(sc);
+#endif
+
splx(s);
+
+ return true;
}
-/*
- * Handle suspend/resume.
- *
- * We need to switch to polling mode here, because this routine is
- * called from an interrupt context. This is all right since we
- * are almost suspended anyway.
- */
-void
-uhci_power(int why, void *v)
+bool
+uhci_suspend(device_t dv)
{
- uhci_softc_t *sc = v;
+ uhci_softc_t *sc = device_private(dv);
int cmd;
int s;
s = splhardusb();
- cmd = UREAD2(sc, UHCI_CMD);
- DPRINTF(("uhci_power: sc=%p, why=%d (was %d), cmd=0x%x\n",
- sc, why, sc->sc_suspend, cmd));
+ cmd = UREAD2(sc, UHCI_CMD);
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
#ifdef UHCI_DEBUG
- if (uhcidebug > 2)
- uhci_dumpregs(sc);
-#endif
- if (sc->sc_intr_xfer != NULL)
- usb_uncallout(sc->sc_poll_handle, uhci_poll_hub,
- sc->sc_intr_xfer);
- sc->sc_bus.use_polling++;
- uhci_run(sc, 0); /* stop the controller */
- cmd &= ~UHCI_CMD_RS;
+ if (uhcidebug > 2)
+ uhci_dumpregs(sc);
+#endif
+ if (sc->sc_intr_xfer != NULL)
+ usb_uncallout(sc->sc_poll_handle, uhci_poll_hub,
+ sc->sc_intr_xfer);
+ sc->sc_bus.use_polling++;
+ uhci_run(sc, 0); /* stop the controller */
+ cmd &= ~UHCI_CMD_RS;
- /* save some state if BIOS doesn't */
- sc->sc_saved_frnum = UREAD2(sc, UHCI_FRNUM);
- sc->sc_saved_sof = UREAD1(sc, UHCI_SOF);
+ /* save some state if BIOS doesn't */
+ sc->sc_saved_frnum = UREAD2(sc, UHCI_FRNUM);
+ sc->sc_saved_sof = UREAD1(sc, UHCI_SOF);
- UWRITE2(sc, UHCI_INTR, 0); /* disable intrs */
+ UWRITE2(sc, UHCI_INTR, 0); /* disable intrs */
+
+ UHCICMD(sc, cmd | UHCI_CMD_EGSM); /* enter suspend */
+ usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
+ sc->sc_bus.use_polling--;
- UHCICMD(sc, cmd | UHCI_CMD_EGSM); /* enter global suspend */
- usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
- sc->sc_suspend = why;
- sc->sc_bus.use_polling--;
- DPRINTF(("uhci_power: cmd=0x%x\n", UREAD2(sc, UHCI_CMD)));
- break;
- case PWR_RESUME:
-#ifdef DIAGNOSTIC
- if (sc->sc_suspend == PWR_RESUME)
- printf("uhci_power: weird, resume without suspend.\n");
-#endif
- sc->sc_bus.use_polling++;
- sc->sc_suspend = why;
- if (cmd & UHCI_CMD_RS)
- uhci_run(sc, 0); /* in case BIOS has started it */
-
- /* restore saved state */
- UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0));
- UWRITE2(sc, UHCI_FRNUM, sc->sc_saved_frnum);
- UWRITE1(sc, UHCI_SOF, sc->sc_saved_sof);
-
- UHCICMD(sc, cmd | UHCI_CMD_FGR); /* force global resume */
- usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
- UHCICMD(sc, cmd & ~UHCI_CMD_EGSM); /* back to normal */
- UHCICMD(sc, UHCI_CMD_MAXP);
- UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
- UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* re-enable intrs */
- uhci_run(sc, 1); /* and start traffic again */
- usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
- sc->sc_bus.use_polling--;
- if (sc->sc_intr_xfer != NULL)
- usb_callout(sc->sc_poll_handle, sc->sc_ival,
- uhci_poll_hub, sc->sc_intr_xfer);
-#ifdef UHCI_DEBUG
- if (uhcidebug > 2)
- uhci_dumpregs(sc);
-#endif
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
- }
splx(s);
+
+ return true;
}
#ifdef UHCI_DEBUG
@@ -1226,7 +1189,7 @@ uhci_intr(void *arg)
{
uhci_softc_t *sc = arg;
- if (sc->sc_dying)
+ if (sc->sc_dying || !device_has_power(&sc->sc_bus.bdev))
return (0);
if (sc->sc_bus.use_polling) {
diff --git a/sys/dev/usb/uhcivar.h b/sys/dev/usb/uhcivar.h
index b0ddd3c45fa..436ff437d02 100644
--- a/sys/dev/usb/uhcivar.h
+++ b/sys/dev/usb/uhcivar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: uhcivar.h,v 1.40 2005/12/27 04:06:45 chs Exp $ */
+/* $NetBSD: uhcivar.h,v 1.41 2007/12/09 20:28:24 jmcneill Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhcivar.h,v 1.14 1999/11/17 22:33:42 n_hibma Exp $ */
/*
@@ -177,9 +177,6 @@ typedef struct uhci_softc {
char sc_vendor[32]; /* vendor string for root hub */
int sc_id_vendor; /* vendor ID for root hub */
- void *sc_powerhook; /* cookie from power hook */
- void *sc_shutdownhook; /* cookie from shutdown hook */
-
#if defined(__NetBSD__) || defined(__OpenBSD__)
device_ptr_t sc_child; /* /dev/usb# device */
#endif
@@ -193,5 +190,7 @@ int uhci_intr(void *);
#if defined(__NetBSD__) || defined(__OpenBSD__)
int uhci_detach(uhci_softc_t *, int);
int uhci_activate(device_ptr_t, enum devact);
+bool uhci_resume(device_t);
+bool uhci_suspend(device_t);
#endif
diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c
index ee93d521354..d4a2f04b955 100644
--- a/sys/dev/usb/uhub.c
+++ b/sys/dev/usb/uhub.c
@@ -1,4 +1,4 @@
-/* $NetBSD: uhub.c,v 1.91 2007/12/01 04:50:50 jmcneill Exp $ */
+/* $NetBSD: uhub.c,v 1.92 2007/12/09 20:28:24 jmcneill Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhub.c,v 1.18 1999/11/17 22:33:43 n_hibma Exp $ */
/*
@@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhub.c,v 1.91 2007/12/01 04:50:50 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhub.c,v 1.92 2007/12/09 20:28:24 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -358,6 +358,9 @@ USB_ATTACH(uhub)
sc->sc_running = 1;
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
USB_ATTACH_SUCCESS_RETURN;
bad:
diff --git a/sys/dev/usb/umass.c b/sys/dev/usb/umass.c
index 507c3f75445..e2fc01bc9cf 100644
--- a/sys/dev/usb/umass.c
+++ b/sys/dev/usb/umass.c
@@ -1,4 +1,4 @@
-/* $NetBSD: umass.c,v 1.124 2007/03/13 13:51:56 drochner Exp $ */
+/* $NetBSD: umass.c,v 1.125 2007/12/09 20:28:24 jmcneill Exp $ */
/*
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -131,7 +131,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umass.c,v 1.124 2007/03/13 13:51:56 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umass.c,v 1.125 2007/12/09 20:28:24 jmcneill Exp $");
#include "atapibus.h"
#include "scsibus.h"
@@ -636,6 +636,9 @@ USB_ATTACH(umass)
usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
USBDEV(sc->sc_dev));
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
DPRINTF(UDMASS_GEN, ("%s: Attach finished\n", USBDEVNAME(sc->sc_dev)));
USB_ATTACH_SUCCESS_RETURN;
@@ -649,6 +652,8 @@ USB_DETACH(umass)
DPRINTF(UDMASS_USB, ("%s: detached\n", USBDEVNAME(sc->sc_dev)));
+ pmf_device_deregister(self);
+
/* Abort the pipes to wake up any waiting processes. */
for (i = 0 ; i < UMASS_NEP ; i++) {
if (sc->sc_pipe[i] != NULL)
diff --git a/sys/dev/usb/usb.c b/sys/dev/usb/usb.c
index 7e714fd663a..f665ea7345a 100644
--- a/sys/dev/usb/usb.c
+++ b/sys/dev/usb/usb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: usb.c,v 1.103 2007/12/05 17:19:56 pooka Exp $ */
+/* $NetBSD: usb.c,v 1.104 2007/12/09 20:28:25 jmcneill Exp $ */
/*
* Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
@@ -44,7 +44,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.103 2007/12/05 17:19:56 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.104 2007/12/09 20:28:25 jmcneill Exp $");
#include "opt_compat_netbsd.h"
@@ -248,6 +248,9 @@ USB_ATTACH(usb)
config_pending_incr();
usb_kthread_create(usb_create_event_thread, sc);
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
USB_ATTACH_SUCCESS_RETURN;
}
diff --git a/sys/dev/wscons/wsdisplay.c b/sys/dev/wscons/wsdisplay.c
index 3e46ba7af52..a1715d68a13 100644
--- a/sys/dev/wscons/wsdisplay.c
+++ b/sys/dev/wscons/wsdisplay.c
@@ -1,4 +1,4 @@
-/* $NetBSD: wsdisplay.c,v 1.112 2007/11/19 18:51:51 ad Exp $ */
+/* $NetBSD: wsdisplay.c,v 1.113 2007/12/09 20:28:25 jmcneill Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsdisplay.c,v 1.112 2007/11/19 18:51:51 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsdisplay.c,v 1.113 2007/12/09 20:28:25 jmcneill Exp $");
#include "opt_wsdisplay_compat.h"
#include "opt_wsmsgattrs.h"
@@ -108,6 +108,7 @@ static void wsdisplay_shutdownhook(void *);
static void wsdisplay_addscreen_print(struct wsdisplay_softc *, int, int);
static void wsdisplay_closescreen(struct wsdisplay_softc *, struct wsscreen *);
int wsdisplay_delscreen(struct wsdisplay_softc *, int, int);
+static void wsdisplay_switchto(int);
#define WSDISPLAY_MAXSCREEN 8
@@ -158,10 +159,12 @@ static int wsdisplay_emul_match(device_t , struct cfdata *, void *);
static void wsdisplay_emul_attach(device_t, device_t, void *);
static int wsdisplay_noemul_match(device_t, struct cfdata *, void *);
static void wsdisplay_noemul_attach(device_t, device_t, void *);
+static bool wsdisplay_resume(device_t dv);
+static bool wsdisplay_suspend(device_t dv);
CFATTACH_DECL_NEW(wsdisplay_emul, sizeof (struct wsdisplay_softc),
wsdisplay_emul_match, wsdisplay_emul_attach, NULL, NULL);
-
+
CFATTACH_DECL_NEW(wsdisplay_noemul, sizeof (struct wsdisplay_softc),
wsdisplay_noemul_match, wsdisplay_noemul_attach, NULL, NULL);
@@ -598,6 +601,21 @@ wsdisplay_noemul_attach(device_t parent, device_t self, void *aux)
ap->accessops, ap->accesscookie);
}
+static bool
+wsdisplay_suspend(device_t dv)
+{
+ wsdisplay_switchtoconsole();
+
+ return true;
+}
+
+static bool
+wsdisplay_resume(device_t dv)
+{
+
+ return true;
+}
+
/* Print function (for parent devices). */
int
wsdisplaydevprint(void *aux, const char *pnp)
@@ -696,6 +714,9 @@ wsdisplay_common_attach(struct wsdisplay_softc *sc, int console, int kbdmux,
if (i > start)
wsdisplay_addscreen_print(sc, start, i-start);
+ if (!pmf_device_register(sc->sc_dev, wsdisplay_suspend, wsdisplay_resume))
+ aprint_error_dev(sc->sc_dev, "couldn't establish power handler\n");
+
if (hookset == 0)
shutdownhook_establish(wsdisplay_shutdownhook, NULL);
hookset = 1;
@@ -2057,18 +2078,15 @@ wsdisplay_unset_cons_kbd(void)
wsdisplay_cons_kbd_pollc = 0;
}
-/*
- * Switch the console display to it's first screen.
- */
-void
-wsdisplay_switchtoconsole(void)
+static void
+wsdisplay_switchto(int no)
{
struct wsdisplay_softc *sc;
struct wsscreen *scr;
if (wsdisplay_console_device != NULL) {
sc = wsdisplay_console_device;
- if ((scr = sc->sc_scr[0]) == NULL)
+ if ((scr = sc->sc_scr[no]) == NULL)
return;
(*sc->sc_accessops->show_screen)(sc->sc_accesscookie,
scr->scr_dconf->emulcookie,
@@ -2077,6 +2095,15 @@ wsdisplay_switchtoconsole(void)
}
/*
+ * Switch the console display to it's first screen.
+ */
+void
+wsdisplay_switchtoconsole(void)
+{
+ wsdisplay_switchto(0);
+}
+
+/*
* Switch the console at shutdown.
*/
static void
diff --git a/sys/dev/wscons/wskbd.c b/sys/dev/wscons/wskbd.c
index cc154617c6d..42abfce3b8a 100644
--- a/sys/dev/wscons/wskbd.c
+++ b/sys/dev/wscons/wskbd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: wskbd.c,v 1.108 2007/12/01 05:22:02 jmcneill Exp $ */
+/* $NetBSD: wskbd.c,v 1.109 2007/12/09 20:28:25 jmcneill Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@@ -79,7 +79,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wskbd.c,v 1.108 2007/12/01 05:22:02 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wskbd.c,v 1.109 2007/12/09 20:28:25 jmcneill Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@@ -464,6 +464,11 @@ wskbd_attach(struct device *parent, struct device *self, void *aux)
sc->sc_base.me_dv.dv_xname, error);
}
#endif
+
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ else if (!pmf_class_input_register(self))
+ aprint_error_dev(self, "couldn't register as input device\n");
}
void
@@ -620,6 +625,8 @@ wskbd_input(struct device *dev, u_int type, int value)
callout_stop(&sc->sc_repeat_ch);
}
+ device_active(dev, DVA_HARDWARE);
+
#if NWSDISPLAY > 0
/*
* If /dev/wskbdN is not connected in event mode translate and
@@ -689,7 +696,7 @@ wskbd_deliver_event(struct wskbd_softc *sc, u_int type, int value)
return;
}
#endif
-
+
event.type = type;
event.value = value;
if (wsevent_inject(evar, &event, 1) != 0)
@@ -1453,6 +1460,18 @@ internal_command(struct wskbd_softc *sc, u_int *type, keysym_t ksym,
u_int state = 0;
#endif
switch (ksym) {
+ case KS_Cmd_VolumeToggle:
+ if (*type == WSCONS_EVENT_KEY_DOWN)
+ pmf_event_inject(NULL, PMFE_AUDIO_VOLUME_TOGGLE);
+ break;
+ case KS_Cmd_VolumeUp:
+ if (*type == WSCONS_EVENT_KEY_DOWN)
+ pmf_event_inject(NULL, PMFE_AUDIO_VOLUME_UP);
+ break;
+ case KS_Cmd_VolumeDown:
+ if (*type == WSCONS_EVENT_KEY_DOWN)
+ pmf_event_inject(NULL, PMFE_AUDIO_VOLUME_DOWN);
+ break;
#ifdef WSDISPLAY_SCROLLSUPPORT
case KS_Cmd_ScrollFastUp:
case KS_Cmd_ScrollFastDown:
diff --git a/sys/dev/wscons/wsksymdef.h b/sys/dev/wscons/wsksymdef.h
index 8bc48f04924..1d082521a87 100644
--- a/sys/dev/wscons/wsksymdef.h
+++ b/sys/dev/wscons/wsksymdef.h
@@ -1,4 +1,4 @@
-/* $NetBSD: wsksymdef.h,v 1.58 2007/04/04 14:50:21 mishka Exp $ */
+/* $NetBSD: wsksymdef.h,v 1.59 2007/12/09 20:28:25 jmcneill Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -524,6 +524,9 @@
#define KS_Cmd_ScrollFastDown 0xf42d
#define KS_Cmd_ScrollSlowUp 0xf42e
#define KS_Cmd_ScrollSlowDown 0xf42f
+#define KS_Cmd_VolumeUp 0xf430
+#define KS_Cmd_VolumeDown 0xf431
+#define KS_Cmd_VolumeToggle 0xf432
/*
* Group 5 (internal)
diff --git a/sys/dev/wscons/wsmouse.c b/sys/dev/wscons/wsmouse.c
index 05bab1a2ebe..4b8cd0616fa 100644
--- a/sys/dev/wscons/wsmouse.c
+++ b/sys/dev/wscons/wsmouse.c
@@ -1,4 +1,4 @@
-/* $NetBSD: wsmouse.c,v 1.54 2007/12/01 05:40:44 jmcneill Exp $ */
+/* $NetBSD: wsmouse.c,v 1.55 2007/12/09 20:28:25 jmcneill Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -111,7 +111,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsmouse.c,v 1.54 2007/12/01 05:40:44 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsmouse.c,v 1.55 2007/12/09 20:28:25 jmcneill Exp $");
#include "wsmouse.h"
#include "wsdisplay.h"
@@ -275,6 +275,9 @@ wsmouse_attach(struct device *parent, struct device *self, void *aux)
aprint_naive("\n");
aprint_normal("\n");
+
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
int