Index: dev/usb/ohci.c =================================================================== RCS file: /home/ncvs/src/sys/dev/usb/ohci.c,v retrieving revision 1.112 diff -u -r1.112 ohci.c --- dev/usb/ohci.c 16 Aug 2002 09:10:43 -0000 1.112 +++ dev/usb/ohci.c 22 Aug 2002 17:41:50 -0000 @@ -982,7 +982,6 @@ /* * Shut down the controller when the system is going down. */ -#if defined(__NetBSD__) || defined(__OpenBSD__) void ohci_shutdown(void *v) { @@ -1014,7 +1013,9 @@ s = splhardusb(); switch (why) { case PWR_SUSPEND: +#if 0 case PWR_STANDBY: +#endif sc->sc_bus.use_polling++; ctl = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK; if (sc->sc_control == 0) { @@ -1052,14 +1053,15 @@ sc->sc_control = sc->sc_intre = 0; sc->sc_bus.use_polling--; break; +#if 0 case PWR_SOFTSUSPEND: case PWR_SOFTSTANDBY: case PWR_SOFTRESUME: break; +#endif } splx(s); } -#endif #ifdef USB_DEBUG void Index: dev/usb/ohcivar.h =================================================================== RCS file: /home/ncvs/src/sys/dev/usb/ohcivar.h,v retrieving revision 1.32 diff -u -r1.32 ohcivar.h --- dev/usb/ohcivar.h 7 Apr 2002 15:16:31 -0000 1.32 +++ dev/usb/ohcivar.h 9 Apr 2002 20:17:55 -0000 @@ -157,4 +157,9 @@ int ohci_activate(device_ptr_t, enum devact); #endif +#if defined(__FreeBSD__) +void ohci_power(int state, void *); +void ohci_shutdown(void *); +#endif + #define MS_TO_TICKS(ms) ((ms) * hz / 1000) Index: i386/apm/apm.c =================================================================== RCS file: /home/ncvs/src/sys/i386/apm/apm.c,v retrieving revision 1.126 diff -u -r1.126 apm.c --- i386/apm/apm.c 20 Mar 2002 05:42:16 -0000 1.126 +++ i386/apm/apm.c 23 Mar 2002 07:53:56 -0000 @@ -243,12 +243,161 @@ return (sc->bios.r.ebx & 0xffff); } + +#ifndef KLD_MODULE +#include +#if __FreeBSD_version >= 500001 +#include +#endif +#define APM_FIVA_HACK +#endif + +#ifdef APM_FIVA_HACK +/* + * CASSIOPEIA FIVA suspend/resume hack by iwasaki@FreeBSD.org + * The following hack was done by the translation from the FIVA + * ACPI data blocks (_PTS and _WAK) into C code. + */ + +/* FIVA _PTS (Prepare To Sleep) */ +static void +apm_fiva_pts(void) +{ + u_int8_t *bdatap, bdata; +#if __FreeBSD_version < 500001 + pcicfgregs cfg; +#endif + + /* + * Store(0x85, \_SB_.PCI0.ISA_.BCMD) + * [aml_region_write(0, 0, 0x85, 0x6ffff2c, 0x0, 0x8)] + */ + pmap_kenter((vm_offset_t)ptvmmap, (0x6ffff2c) & ~PAGE_MASK); + bdatap = (u_int8_t *) &ptvmmap[0x6ffff2c & PAGE_MASK]; + *bdatap = 0x85; + + /* + * Store(0x0, \_SB_.PCI0.ISA_.SMIC) + * [aml_region_write(1, 0, 0x0, 0x8038, 0x0, 0x8)] + */ + outb(0x8038, 0x0); + + /* + * Store(0x81, \_SB_.PCI0.ISA_.BCMD) + * [aml_region_write(0, 0, 0x81, 0x6ffff2c, 0x0, 0x8)] + */ + *bdatap = 0x81; + + /* + * Store(0x0, \_SB_.PCI0.ISA_.SMIC) + * [aml_region_write(1, 0, 0x0, 0x8038, 0x0, 0x8)] + */ + outb(0x8038, 0x0); + + /* + * Store(0x0, \_SB_.PCI0.PM__.PPCM) + * [aml_region_write(2, 1, 0x0, 0x0, 0x454, 0x1)] + * Note: pciconf -v -l gives us the following; + * chip1@pci0:17:0: + * class=0x068000 card=0x00000000 chip=0x710110b9 rev=0x00 hdr=0x00 + * vendor = 'Acer Labs Inc.' + * device = 'M7101 Power Management Controller' + * class = bridge + * subclass = PCI-unknown + */ +#if __FreeBSD_version >= 500001 + if (!pci_cfgregopen()) + return; + bdata = pci_cfgregread(0, 17, 0, 0x8a, 1); + bdata &= ~(1 << 4); + if (!pci_cfgregopen()) + return; + pci_cfgregwrite(0, 17, 0, 0x8a, bdata, 1); +#else + cfg.bus = 0; cfg.slot = 17; cfg.func = 0; + bdata = (u_int8_t)pci_cfgread(&cfg, 0x8a, 1); + bdata &= ~(1 << 4); + pci_cfgwrite(&cfg, 0x8a, (u_int32_t)bdata, 1); +#endif + + /* + * Store(0x0, \_SB_.PCI0.PM__.PVGA) + * [aml_region_write(2, 1, 0x0, 0x0, 0x455, 0x1)] + */ +#if __FreeBSD_version >= 500001 + if (!pci_cfgregopen()) + return; + bdata = pci_cfgregread(0, 17, 0, 0x8a, 1); + bdata &= ~(1 << 5); + if (!pci_cfgregopen()) + return; + pci_cfgregwrite(0, 17, 0, 0x8a, bdata, 1); +#else + bdata = (u_int8_t)pci_cfgread(&cfg, 0x8a, 1); + bdata &= ~(1 << 5); + pci_cfgwrite(&cfg, 0x8a, (u_int32_t)bdata, 1); +#endif + + pmap_kremove((vm_offset_t)ptvmmap); +} + +/* FIVA _WAK (Wakeup) */ +static void +apm_fiva_wak(void) +{ + u_int8_t bdata; +#if __FreeBSD_version < 500001 + pcicfgregs cfg; +#endif + + /* + * Store(0x1, \_SB_.PCI0.PM__.PPCM) + * [aml_region_write(2, 1, 0x1, 0x0, 0x454, 0x1)] + */ +#if __FreeBSD_version >= 500001 + if (!pci_cfgregopen()) + return; + bdata = pci_cfgregread(0, 17, 0, 0x8a, 1); + bdata |= (1 << 4); + if (!pci_cfgregopen()) + return; + pci_cfgregwrite(0, 17, 0, 0x8a, bdata, 1); +#else + cfg.bus = 0; cfg.slot = 17; cfg.func = 0; + bdata = (u_int8_t)pci_cfgread(&cfg, 0x8a, 1); + bdata |= (1 << 4); + pci_cfgwrite(&cfg, 0x8a, (u_int32_t)bdata, 1); +#endif + + /* + * Store(0x1, \_SB_.PCI0.PM__.PVGA) + * [aml_region_write(2, 1, 0x1, 0x0, 0x455, 0x1)] + */ +#if __FreeBSD_version >= 500001 + if (!pci_cfgregopen()) + return; + bdata = pci_cfgregread(0, 17, 0, 0x8a, 1); + bdata |= (1 << 5); + if (!pci_cfgregopen()) + return; + pci_cfgregwrite(0, 17, 0, 0x8a, bdata, 1); +#else + bdata = (u_int8_t)pci_cfgread(&cfg, 0x8a, 1); + bdata |= (1 << 5); + pci_cfgwrite(&cfg, 0x8a, (u_int32_t)bdata, 1); +#endif +} +#endif + /* suspend entire system */ static int apm_suspend_system(int state) { struct apm_softc *sc = &apm_softc; +#ifdef APM_FIVA_HACK + apm_fiva_pts(); +#endif sc->bios.r.eax = (APM_BIOS << 8) | APM_SETPWSTATE; sc->bios.r.ebx = PMDV_ALLDEV; sc->bios.r.ecx = state; @@ -543,6 +692,9 @@ return; sc->suspending = 0; +#ifdef APM_FIVA_HACK + apm_fiva_wak(); +#endif if (sc->initialized) { apm_execute_hook(hook[APM_HOOK_RESUME]); DEVICE_RESUME(root_bus); Index: pci/ohci_pci.c =================================================================== RCS file: /home/ncvs/src/sys/pci/ohci_pci.c,v retrieving revision 1.28 diff -u -r1.28 ohci_pci.c --- pci/ohci_pci.c 18 Aug 2002 11:52:47 -0000 1.28 +++ pci/ohci_pci.c 22 Aug 2002 17:43:26 -0000 @@ -114,6 +114,48 @@ static int ohci_pci_attach(device_t self); static int ohci_pci_detach(device_t self); +static int ohci_pci_suspend(device_t self); +static int ohci_pci_resume(device_t self); +static int ohci_pci_shutdown(device_t self); + +static int +ohci_pci_suspend(device_t self) +{ + ohci_softc_t *sc = device_get_softc(self); + int err; + + err = bus_generic_suspend(self); + if (err) + return err; + ohci_power(PWR_SUSPEND, sc); + + return 0; +} + +static int +ohci_pci_resume(device_t self) +{ + ohci_softc_t *sc = device_get_softc(self); + + ohci_power(PWR_RESUME, sc); + bus_generic_resume(self); + + return 0; +} + +static int +ohci_pci_shutdown(device_t self) +{ + ohci_softc_t *sc = device_get_softc(self); + int err; + + err = bus_generic_shutdown(self); + if (err) + return err; + ohci_shutdown(sc); + + return 0; +} static const char * ohci_pci_match(device_t self) @@ -295,9 +337,11 @@ static device_method_t ohci_methods[] = { /* Device interface */ - DEVMETHOD(device_probe, ohci_pci_probe), - DEVMETHOD(device_attach, ohci_pci_attach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_probe, ohci_pci_probe), + DEVMETHOD(device_attach, ohci_pci_attach), + DEVMETHOD(device_suspend, ohci_pci_suspend), + DEVMETHOD(device_resume, ohci_pci_resume), + DEVMETHOD(device_shutdown, ohci_pci_shutdown), /* Bus interface */ DEVMETHOD(bus_print_child, bus_generic_print_child),