Index: dev/usb/ohci.c =================================================================== RCS file: /home/ncvs/src/sys/dev/usb/ohci.c,v retrieving revision 1.53 diff -u -r1.53 ohci.c --- dev/usb/ohci.c 12 Sep 2001 08:37:15 -0000 1.53 +++ dev/usb/ohci.c 15 Dec 2001 15:24:07 -0000 @@ -823,6 +823,7 @@ sc->sc_bus.methods = &ohci_bus_methods; sc->sc_bus.pipe_size = sizeof(struct ohci_pipe); + sc->sc_control = sc->sc_intre = 0; #if defined(__NetBSD__) sc->sc_powerhook = powerhook_establish(ohci_power, sc); sc->sc_shutdownhook = shutdownhook_establish(ohci_shutdown, sc); @@ -899,7 +900,6 @@ /* * Shut down the controller when the system is going down. */ -#if defined(__NetBSD__) || defined(__OpenBSD__) void ohci_shutdown(v) void *v; @@ -918,19 +918,69 @@ * are almost suspended anyway. */ void -ohci_power(why, v) - int why; - void *v; +ohci_power(int why, void *v) { -#ifdef OHCI_DEBUG ohci_softc_t *sc = v; + u_int32_t ctl; + int s; +#ifdef OHCI_DEBUG DPRINTF(("ohci_power: sc=%p, why=%d\n", sc, why)); - /* XXX should suspend/resume */ ohci_dumpregs(sc); #endif -} + + s = splusb(); + 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) { + /* + * 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; +#if 0 + case PWR_SOFTSUSPEND: + case PWR_SOFTSTANDBY: + case PWR_SOFTRESUME: + break; +#endif + } + splx(s); +} #ifdef OHCI_DEBUG void Index: dev/usb/ohcivar.h =================================================================== RCS file: /home/ncvs/src/sys/dev/usb/ohcivar.h,v retrieving revision 1.22 diff -u -r1.22 ohcivar.h --- dev/usb/ohcivar.h 17 Jul 2000 18:41:19 -0000 1.22 +++ dev/usb/ohcivar.h 15 Dec 2001 15:24:07 -0000 @@ -118,6 +118,8 @@ void *sc_powerhook; void *sc_shutdownhook; /* cookie from shutdown hook */ #endif + u_int32_t sc_control; /* Preserved during suspend/standby */ + u_int32_t sc_intre; device_ptr_t sc_child; } ohci_softc_t; @@ -127,6 +129,11 @@ #if defined(__NetBSD__) || defined(__OpenBSD__) int ohci_detach(ohci_softc_t *, int); 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.124 diff -u -r1.124 apm.c --- i386/apm/apm.c 1 Nov 2001 16:33:31 -0000 1.124 +++ i386/apm/apm.c 15 Dec 2001 15:24:07 -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: isa/syscons_isa.c =================================================================== RCS file: /home/ncvs/src/sys/isa/syscons_isa.c,v retrieving revision 1.17 diff -u -r1.17 syscons_isa.c --- isa/syscons_isa.c 30 Jun 2001 10:15:06 -0000 1.17 +++ isa/syscons_isa.c 15 Dec 2001 15:24:07 -0000 @@ -88,6 +88,39 @@ return sc_attach_unit(device_get_unit(dev), device_get_flags(dev)); } +static int sc_cur_scr; + +static int +scsuspend(device_t dev) +{ + int retry = 10; + static int dummy; + sc_softc_t *sc; + + sc = &main_softc; + sc_cur_scr = sc->cur_scp->index; + do { + sc_switch_scr(sc, 0); + if (!sc->switch_in_progress) { + break; + } + tsleep(&dummy, 0, "scsuspend", 100); + } while (retry--); + + return (0); +} + +static int +scresume(device_t dev) +{ + sc_softc_t *sc; + + sc = &main_softc; + sc_switch_scr(sc, sc_cur_scr); + + return (0); +} + int sc_max_unit(void) { @@ -230,6 +263,8 @@ DEVMETHOD(device_identify, scidentify), DEVMETHOD(device_probe, scprobe), DEVMETHOD(device_attach, scattach), + DEVMETHOD(device_suspend, scsuspend), + DEVMETHOD(device_resume, scresume), { 0, 0 } }; Index: modules/vga_pci/Makefile =================================================================== RCS file: modules/vga_pci/Makefile diff -N modules/vga_pci/Makefile --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/vga_pci/Makefile 15 Dec 2001 17:32:23 -0000 @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../pci + +KMOD= vga_pci +SRCS= vga_pci.c device_if.h bus_if.h pci_if.h + +.include Index: pci/ohci_pci.c =================================================================== RCS file: /home/ncvs/src/sys/pci/ohci_pci.c,v retrieving revision 1.25 diff -u -r1.25 ohci_pci.c --- pci/ohci_pci.c 6 Nov 2001 23:44:03 -0000 1.25 +++ pci/ohci_pci.c 15 Dec 2001 15:24:07 -0000 @@ -98,6 +98,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) @@ -272,6 +314,7 @@ /* XXX or should we panic? */ device_printf(self, "Could not tear down irq, %d\n", err); + bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res); sc->irq_res = NULL; } @@ -280,11 +323,6 @@ sc->sc_bus.bdev = NULL; } - if (sc->irq_res) { - bus_release_resource(self, SYS_RES_IOPORT, 0, sc->irq_res); - sc->irq_res = NULL; - } - if (sc->io_res) { bus_release_resource(self, SYS_RES_MEMORY,PCI_CBMEM,sc->io_res); sc->io_res = NULL; @@ -299,7 +337,9 @@ /* Device interface */ DEVMETHOD(device_probe, ohci_pci_probe), DEVMETHOD(device_attach, ohci_pci_attach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), + 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), Index: pci/vga_pci.c =================================================================== RCS file: pci/vga_pci.c diff -N pci/vga_pci.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ pci/vga_pci.c 15 Dec 2001 17:20:53 -0000 @@ -0,0 +1,79 @@ +#include +#include +#include +#include + +#include +#include + +static void vga_pci_identify(driver_t *driver, device_t parent); +static int vga_pci_attach(device_t dev); +static int vga_pci_probe(device_t dev); +static int vga_pci_suspend(device_t dev); +static int vga_pci_resume(device_t dev); + +static device_method_t vga_pci_methods[] = { + /* Device interface. */ + DEVMETHOD(device_identify, vga_pci_identify), + DEVMETHOD(device_probe, vga_pci_probe), + DEVMETHOD(device_attach, vga_pci_attach), + DEVMETHOD(device_suspend, vga_pci_suspend), + DEVMETHOD(device_resume, vga_pci_resume), + + { 0, 0 } +}; + +static driver_t vga_pci_driver = { + "vga_pci", + vga_pci_methods, + 0, +}; + +static devclass_t vga_pci_devclass; + +DRIVER_MODULE(vga_pci, pci, vga_pci_driver, vga_pci_devclass, 0, 0); + +static void +vga_pci_identify(driver_t *driver, device_t parent) +{ + + BUS_ADD_CHILD(parent, 255, "vga_pci", 0); +} + +static int +vga_pci_probe(device_t dev) +{ + + if (pci_get_class(dev) == PCIC_DISPLAY && + pci_get_subclass(dev) == PCIS_DISPLAY_VGA) { + device_set_desc(dev, "Generic PCI VGA"); + return (0); + } + + return (ENXIO); +} + +static int +vga_pci_attach(device_t dev) +{ + + return (0); +} + +static int +vga_pci_suspend(device_t dev) +{ + + pci_set_powerstate(dev, PCI_POWERSTATE_D2); + DELAY(100000); + return (0); +} + +static int +vga_pci_resume(device_t dev) +{ + + pci_set_powerstate(dev, PCI_POWERSTATE_D0); + return (0); +} +