18a997770SDoug Rabson /*- 28a997770SDoug Rabson * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 38a997770SDoug Rabson * All rights reserved. 48a997770SDoug Rabson * 58a997770SDoug Rabson * Redistribution and use in source and binary forms, with or without 68a997770SDoug Rabson * modification, are permitted provided that the following conditions 78a997770SDoug Rabson * are met: 88a997770SDoug Rabson * 1. Redistributions of source code must retain the above copyright 98a997770SDoug Rabson * notice, this list of conditions and the following disclaimer as 108a997770SDoug Rabson * the first lines of this file unmodified. 118a997770SDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright 128a997770SDoug Rabson * notice, this list of conditions and the following disclaimer in the 138a997770SDoug Rabson * documentation and/or other materials provided with the distribution. 148a997770SDoug Rabson * 158a997770SDoug Rabson * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 168a997770SDoug Rabson * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 178a997770SDoug Rabson * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 188a997770SDoug Rabson * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 198a997770SDoug Rabson * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 208a997770SDoug Rabson * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 218a997770SDoug Rabson * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 228a997770SDoug Rabson * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 238a997770SDoug Rabson * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 248a997770SDoug Rabson * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 258a997770SDoug Rabson */ 268a997770SDoug Rabson 278c9bbf48SDavid E. O'Brien #include <sys/cdefs.h> 288c9bbf48SDavid E. O'Brien __FBSDID("$FreeBSD$"); 298c9bbf48SDavid E. O'Brien 308a997770SDoug Rabson #include "opt_syscons.h" 318a997770SDoug Rabson 328a997770SDoug Rabson #include <sys/param.h> 338a997770SDoug Rabson #include <sys/systm.h> 348a997770SDoug Rabson #include <sys/kernel.h> 358a997770SDoug Rabson #include <sys/module.h> 368a997770SDoug Rabson #include <sys/bus.h> 37ce9edcf5SPoul-Henning Kamp #include <sys/cons.h> 3800d25f51SPoul-Henning Kamp #include <sys/kbio.h> 3900d25f51SPoul-Henning Kamp #include <sys/consio.h> 40dcb65c59SMatthew N. Dodd #include <sys/sysctl.h> 416e8394b8SKazutaka YOKOTA 4221691935SPeter Wemm #if defined(__i386__) || defined(__amd64__) 436e8394b8SKazutaka YOKOTA 446e8394b8SKazutaka YOKOTA #include <machine/clock.h> 456e8394b8SKazutaka YOKOTA #include <machine/md_var.h> 466e8394b8SKazutaka YOKOTA #include <machine/pc/bios.h> 476e8394b8SKazutaka YOKOTA 486e8394b8SKazutaka YOKOTA #include <vm/vm.h> 496e8394b8SKazutaka YOKOTA #include <vm/pmap.h> 50092a5c45SJohn Baldwin #include <vm/vm_param.h> 516e8394b8SKazutaka YOKOTA 526e8394b8SKazutaka YOKOTA #define BIOS_CLKED (1 << 6) 536e8394b8SKazutaka YOKOTA #define BIOS_NLKED (1 << 5) 546e8394b8SKazutaka YOKOTA #define BIOS_SLKED (1 << 4) 556e8394b8SKazutaka YOKOTA #define BIOS_ALKED 0 566e8394b8SKazutaka YOKOTA 5721691935SPeter Wemm #endif 588a997770SDoug Rabson 598a997770SDoug Rabson #include <dev/syscons/syscons.h> 608a997770SDoug Rabson 618a997770SDoug Rabson #include <isa/isavar.h> 628a997770SDoug Rabson 635fa7c51fSRink Springer #include "opt_xbox.h" 645fa7c51fSRink Springer 655fa7c51fSRink Springer #ifdef XBOX 665fa7c51fSRink Springer #include <machine/xbox.h> 675fa7c51fSRink Springer #endif 685fa7c51fSRink Springer 696e8394b8SKazutaka YOKOTA static devclass_t sc_devclass; 708a997770SDoug Rabson 71e2f29c6eSKazutaka YOKOTA static sc_softc_t main_softc; 72dcb65c59SMatthew N. Dodd #ifdef SC_NO_SUSPEND_VTYSWITCH 73dcb65c59SMatthew N. Dodd static int sc_no_suspend_vtswitch = 1; 74dcb65c59SMatthew N. Dodd #else 75dcb65c59SMatthew N. Dodd static int sc_no_suspend_vtswitch = 0; 76dcb65c59SMatthew N. Dodd #endif 77dcb65c59SMatthew N. Dodd static int sc_cur_scr; 78dcb65c59SMatthew N. Dodd 79b4f9625aSJung-uk Kim TUNABLE_INT("hw.syscons.sc_no_suspend_vtswitch", &sc_no_suspend_vtswitch); 80dcb65c59SMatthew N. Dodd SYSCTL_DECL(_hw_syscons); 81dcb65c59SMatthew N. Dodd SYSCTL_INT(_hw_syscons, OID_AUTO, sc_no_suspend_vtswitch, CTLFLAG_RW, 82dcb65c59SMatthew N. Dodd &sc_no_suspend_vtswitch, 0, "Disable VT switch before suspend."); 836e8394b8SKazutaka YOKOTA 84c20ac811SPeter Wemm static void 85c20ac811SPeter Wemm scidentify(driver_t *driver, device_t parent) 86c20ac811SPeter Wemm { 87b4f9625aSJung-uk Kim 88c20ac811SPeter Wemm BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "sc", 0); 89c20ac811SPeter Wemm } 90c20ac811SPeter Wemm 918a997770SDoug Rabson static int 928a997770SDoug Rabson scprobe(device_t dev) 938a997770SDoug Rabson { 94b4f9625aSJung-uk Kim 95f7f2df54SDoug Rabson /* No pnp support */ 96f7f2df54SDoug Rabson if (isa_get_vendorid(dev)) 97f7f2df54SDoug Rabson return (ENXIO); 98f7f2df54SDoug Rabson 998a997770SDoug Rabson device_set_desc(dev, "System console"); 100b4f9625aSJung-uk Kim return (sc_probe_unit(device_get_unit(dev), device_get_flags(dev))); 1018a997770SDoug Rabson } 1028a997770SDoug Rabson 1038a997770SDoug Rabson static int 1048a997770SDoug Rabson scattach(device_t dev) 1058a997770SDoug Rabson { 106b5b361cbSJohn Baldwin 107b5b361cbSJohn Baldwin return (sc_attach_unit(device_get_unit(dev), device_get_flags(dev) | 108b5b361cbSJohn Baldwin SC_AUTODETECT_KBD)); 1098a997770SDoug Rabson } 1108a997770SDoug Rabson 1119c4d34dfSMitsuru IWASAKI static int 1129c4d34dfSMitsuru IWASAKI scsuspend(device_t dev) 1139c4d34dfSMitsuru IWASAKI { 1149c4d34dfSMitsuru IWASAKI int retry = 10; 1159c4d34dfSMitsuru IWASAKI sc_softc_t *sc; 1169c4d34dfSMitsuru IWASAKI 1179c4d34dfSMitsuru IWASAKI sc = &main_softc; 118e8c321c9SNate Lawson 119dd962f5bSJung-uk Kim if (sc->cur_scp == NULL || sc->suspend_in_progress) 120e8c321c9SNate Lawson return (0); 121e8c321c9SNate Lawson 122dd962f5bSJung-uk Kim if (!sc_no_suspend_vtswitch) { 1239c4d34dfSMitsuru IWASAKI sc_cur_scr = sc->cur_scp->index; 1249c4d34dfSMitsuru IWASAKI do { 1259c4d34dfSMitsuru IWASAKI sc_switch_scr(sc, 0); 126*fa091a48SJung-uk Kim if (!sc->switch_in_progress) 1279c4d34dfSMitsuru IWASAKI break; 12884d37a46SJohn Baldwin pause("scsuspend", hz); 1299c4d34dfSMitsuru IWASAKI } while (retry--); 130dd962f5bSJung-uk Kim } 131dd962f5bSJung-uk Kim 132dd962f5bSJung-uk Kim sc->suspend_in_progress = TRUE; 1339c4d34dfSMitsuru IWASAKI 1349c4d34dfSMitsuru IWASAKI return (0); 1359c4d34dfSMitsuru IWASAKI } 1369c4d34dfSMitsuru IWASAKI 1379c4d34dfSMitsuru IWASAKI static int 1389c4d34dfSMitsuru IWASAKI scresume(device_t dev) 1399c4d34dfSMitsuru IWASAKI { 1409c4d34dfSMitsuru IWASAKI sc_softc_t *sc; 1419c4d34dfSMitsuru IWASAKI 142dd962f5bSJung-uk Kim sc = &main_softc; 143dd962f5bSJung-uk Kim 144dd962f5bSJung-uk Kim if (!sc->suspend_in_progress) 145dcb65c59SMatthew N. Dodd return (0); 146dcb65c59SMatthew N. Dodd 147dd962f5bSJung-uk Kim sc->suspend_in_progress = FALSE; 148dd962f5bSJung-uk Kim 149dd962f5bSJung-uk Kim if (!sc_no_suspend_vtswitch) 1509c4d34dfSMitsuru IWASAKI sc_switch_scr(sc, sc_cur_scr); 1519c4d34dfSMitsuru IWASAKI 1529c4d34dfSMitsuru IWASAKI return (0); 1539c4d34dfSMitsuru IWASAKI } 1549c4d34dfSMitsuru IWASAKI 1556e8394b8SKazutaka YOKOTA int 1566e8394b8SKazutaka YOKOTA sc_max_unit(void) 1576e8394b8SKazutaka YOKOTA { 158b4f9625aSJung-uk Kim 159b4f9625aSJung-uk Kim return (devclass_get_maxunit(sc_devclass)); 1606e8394b8SKazutaka YOKOTA } 1616e8394b8SKazutaka YOKOTA 1626e8394b8SKazutaka YOKOTA sc_softc_t 1636e8394b8SKazutaka YOKOTA *sc_get_softc(int unit, int flags) 1646e8394b8SKazutaka YOKOTA { 1656e8394b8SKazutaka YOKOTA sc_softc_t *sc; 1666e8394b8SKazutaka YOKOTA 1678f8e5879SPeter Wemm if (unit < 0) 168b4f9625aSJung-uk Kim return (NULL); 169b4f9625aSJung-uk Kim if ((flags & SC_KERNEL_CONSOLE) != 0) { 1706e8394b8SKazutaka YOKOTA /* FIXME: clear if it is wired to another unit! */ 171e2f29c6eSKazutaka YOKOTA sc = &main_softc; 1726e8394b8SKazutaka YOKOTA } else { 173b4f9625aSJung-uk Kim sc = device_get_softc(devclass_get_device(sc_devclass, unit)); 1748f8e5879SPeter Wemm if (sc == NULL) 175b4f9625aSJung-uk Kim return (NULL); 176e2f29c6eSKazutaka YOKOTA } 1776e8394b8SKazutaka YOKOTA sc->unit = unit; 178b4f9625aSJung-uk Kim if ((sc->flags & SC_INIT_DONE) == 0) { 1796e8394b8SKazutaka YOKOTA sc->keyboard = -1; 1806e8394b8SKazutaka YOKOTA sc->adapter = -1; 18109132359SKazutaka YOKOTA sc->cursor_char = SC_CURSOR_CHAR; 182e2f29c6eSKazutaka YOKOTA sc->mouse_char = SC_MOUSE_CHAR; 1836e8394b8SKazutaka YOKOTA } 184b4f9625aSJung-uk Kim return (sc); 1856e8394b8SKazutaka YOKOTA } 1866e8394b8SKazutaka YOKOTA 1876e8394b8SKazutaka YOKOTA sc_softc_t 1886e8394b8SKazutaka YOKOTA *sc_find_softc(struct video_adapter *adp, struct keyboard *kbd) 1896e8394b8SKazutaka YOKOTA { 1906e8394b8SKazutaka YOKOTA sc_softc_t *sc; 1916e8394b8SKazutaka YOKOTA int i; 192b4f9625aSJung-uk Kim int units; 1936e8394b8SKazutaka YOKOTA 1946e8394b8SKazutaka YOKOTA sc = &main_softc; 195b4f9625aSJung-uk Kim if ((adp == NULL || adp == sc->adp) && 196b4f9625aSJung-uk Kim (kbd == NULL || kbd == sc->kbd)) 197b4f9625aSJung-uk Kim return (sc); 1986e8394b8SKazutaka YOKOTA units = devclass_get_maxunit(sc_devclass); 1996e8394b8SKazutaka YOKOTA for (i = 0; i < units; ++i) { 200b4f9625aSJung-uk Kim sc = device_get_softc(devclass_get_device(sc_devclass, i)); 2016e8394b8SKazutaka YOKOTA if (sc == NULL) 2026e8394b8SKazutaka YOKOTA continue; 203b4f9625aSJung-uk Kim if ((adp == NULL || adp == sc->adp) && 204b4f9625aSJung-uk Kim (kbd == NULL || kbd == sc->kbd)) 205b4f9625aSJung-uk Kim return (sc); 2066e8394b8SKazutaka YOKOTA } 207b4f9625aSJung-uk Kim return (NULL); 2086e8394b8SKazutaka YOKOTA } 2096e8394b8SKazutaka YOKOTA 2106e8394b8SKazutaka YOKOTA int 2116e8394b8SKazutaka YOKOTA sc_get_cons_priority(int *unit, int *flags) 2126e8394b8SKazutaka YOKOTA { 213c864c67bSPeter Wemm const char *at; 214*fa091a48SJung-uk Kim int f, u; 2156e8394b8SKazutaka YOKOTA 2165fa7c51fSRink Springer #ifdef XBOX 2175fa7c51fSRink Springer /* 2185fa7c51fSRink Springer * The XBox Loader does not support hints, which makes our initial 2195fa7c51fSRink Springer * console probe fail. Therefore, if an XBox is found, we hardcode the 2205fa7c51fSRink Springer * existence of the console, as it is always there anyway. 2215fa7c51fSRink Springer */ 2225fa7c51fSRink Springer if (arch_i386_is_xbox) { 2235fa7c51fSRink Springer *unit = 0; 2245fa7c51fSRink Springer *flags = SC_KERNEL_CONSOLE; 225b4f9625aSJung-uk Kim return (CN_INTERNAL); 2265fa7c51fSRink Springer } 2275fa7c51fSRink Springer #endif 2285fa7c51fSRink Springer 2296e8394b8SKazutaka YOKOTA *unit = -1; 23081e3fd99SPeter Wemm for (u = 0; u < 16; u++) { 2318a9bc9c0SJohn Baldwin if (resource_disabled(SC_DRIVER_NAME, u)) 2326e8394b8SKazutaka YOKOTA continue; 23381e3fd99SPeter Wemm if (resource_string_value(SC_DRIVER_NAME, u, "at", &at) != 0) 23481e3fd99SPeter Wemm continue; 2356e8394b8SKazutaka YOKOTA if (resource_int_value(SC_DRIVER_NAME, u, "flags", &f) != 0) 2366e8394b8SKazutaka YOKOTA f = 0; 2376e8394b8SKazutaka YOKOTA if (f & SC_KERNEL_CONSOLE) { 2386e8394b8SKazutaka YOKOTA /* the user designates this unit to be the console */ 2396e8394b8SKazutaka YOKOTA *unit = u; 2406e8394b8SKazutaka YOKOTA *flags = f; 2416e8394b8SKazutaka YOKOTA break; 2426e8394b8SKazutaka YOKOTA } 2436e8394b8SKazutaka YOKOTA if (*unit < 0) { 2446e8394b8SKazutaka YOKOTA /* ...otherwise remember the first found unit */ 2456e8394b8SKazutaka YOKOTA *unit = u; 2466e8394b8SKazutaka YOKOTA *flags = f; 2476e8394b8SKazutaka YOKOTA } 2486e8394b8SKazutaka YOKOTA } 249b5b361cbSJohn Baldwin if (*unit < 0) { 250b5b361cbSJohn Baldwin *unit = 0; 251b5b361cbSJohn Baldwin *flags = 0; 252b5b361cbSJohn Baldwin } 2536e8394b8SKazutaka YOKOTA #if 0 254b4f9625aSJung-uk Kim return ((*flags & SC_KERNEL_CONSOLE) != 0 ? CN_INTERNAL : CN_NORMAL); 2556e8394b8SKazutaka YOKOTA #endif 256b4f9625aSJung-uk Kim return (CN_INTERNAL); 2576e8394b8SKazutaka YOKOTA } 2586e8394b8SKazutaka YOKOTA 2596e8394b8SKazutaka YOKOTA void 2606e8394b8SKazutaka YOKOTA sc_get_bios_values(bios_values_t *values) 2616e8394b8SKazutaka YOKOTA { 26221691935SPeter Wemm #if defined(__i386__) || defined(__amd64__) 263b4f9625aSJung-uk Kim uint8_t shift; 2646e8394b8SKazutaka YOKOTA 265b4f9625aSJung-uk Kim values->cursor_start = *(uint8_t *)BIOS_PADDRTOVADDR(0x461); 266b4f9625aSJung-uk Kim values->cursor_end = *(uint8_t *)BIOS_PADDRTOVADDR(0x460); 267b4f9625aSJung-uk Kim shift = *(uint8_t *)BIOS_PADDRTOVADDR(0x417); 268b4f9625aSJung-uk Kim values->shift_state = ((shift & BIOS_CLKED) != 0 ? CLKED : 0) | 269b4f9625aSJung-uk Kim ((shift & BIOS_NLKED) != 0 ? NLKED : 0) | 270b4f9625aSJung-uk Kim ((shift & BIOS_SLKED) != 0 ? SLKED : 0) | 271b4f9625aSJung-uk Kim ((shift & BIOS_ALKED) != 0 ? ALKED : 0); 27221691935SPeter Wemm #else 2736e8394b8SKazutaka YOKOTA values->cursor_start = 0; 2746e8394b8SKazutaka YOKOTA values->cursor_end = 32; 2756e8394b8SKazutaka YOKOTA values->shift_state = 0; 27621691935SPeter Wemm #endif 2776e8394b8SKazutaka YOKOTA values->bell_pitch = BELL_PITCH; 2786e8394b8SKazutaka YOKOTA } 2796e8394b8SKazutaka YOKOTA 2806e8394b8SKazutaka YOKOTA int 2816e8394b8SKazutaka YOKOTA sc_tone(int herz) 2826e8394b8SKazutaka YOKOTA { 283b4f9625aSJung-uk Kim 2841d73a9dcSPoul-Henning Kamp #if defined(HAS_TIMER_SPKR) 2856e8394b8SKazutaka YOKOTA if (herz) { 28624072ca3SYoshihiro Takahashi if (timer_spkr_acquire()) 287b4f9625aSJung-uk Kim return (EBUSY); 288e4659858SPoul-Henning Kamp timer_spkr_setfreq(herz); 289b4f9625aSJung-uk Kim } else 29024072ca3SYoshihiro Takahashi timer_spkr_release(); 29121691935SPeter Wemm #endif 2926e8394b8SKazutaka YOKOTA 293b4f9625aSJung-uk Kim return (0); 2946e8394b8SKazutaka YOKOTA } 2956e8394b8SKazutaka YOKOTA 296c20ac811SPeter Wemm static device_method_t sc_methods[] = { 297c20ac811SPeter Wemm DEVMETHOD(device_identify, scidentify), 298c20ac811SPeter Wemm DEVMETHOD(device_probe, scprobe), 299c20ac811SPeter Wemm DEVMETHOD(device_attach, scattach), 3009c4d34dfSMitsuru IWASAKI DEVMETHOD(device_suspend, scsuspend), 3019c4d34dfSMitsuru IWASAKI DEVMETHOD(device_resume, scresume), 302c20ac811SPeter Wemm { 0, 0 } 303c20ac811SPeter Wemm }; 304c20ac811SPeter Wemm 305c20ac811SPeter Wemm static driver_t sc_driver = { 306c20ac811SPeter Wemm SC_DRIVER_NAME, 307c20ac811SPeter Wemm sc_methods, 308c20ac811SPeter Wemm sizeof(sc_softc_t), 309c20ac811SPeter Wemm }; 310c20ac811SPeter Wemm 3118a997770SDoug Rabson DRIVER_MODULE(sc, isa, sc_driver, sc_devclass, 0, 0); 312dd962f5bSJung-uk Kim 313dd962f5bSJung-uk Kim static devclass_t scpm_devclass; 314dd962f5bSJung-uk Kim 315dd962f5bSJung-uk Kim static void 316dd962f5bSJung-uk Kim scpm_identify(driver_t *driver, device_t parent) 317dd962f5bSJung-uk Kim { 318dd962f5bSJung-uk Kim 319dd962f5bSJung-uk Kim device_add_child(parent, "scpm", 0); 320dd962f5bSJung-uk Kim } 321dd962f5bSJung-uk Kim 322dd962f5bSJung-uk Kim static int 323dd962f5bSJung-uk Kim scpm_probe(device_t dev) 324dd962f5bSJung-uk Kim { 325dd962f5bSJung-uk Kim 326dd962f5bSJung-uk Kim device_set_desc(dev, SC_DRIVER_NAME " suspend/resume"); 327dd962f5bSJung-uk Kim device_quiet(dev); 328dd962f5bSJung-uk Kim 329dd962f5bSJung-uk Kim return (BUS_PROBE_DEFAULT); 330dd962f5bSJung-uk Kim } 331dd962f5bSJung-uk Kim 332dd962f5bSJung-uk Kim static int 333dd962f5bSJung-uk Kim scpm_attach(device_t dev) 334dd962f5bSJung-uk Kim { 335dd962f5bSJung-uk Kim 336dd962f5bSJung-uk Kim bus_generic_probe(dev); 337dd962f5bSJung-uk Kim bus_generic_attach(dev); 338dd962f5bSJung-uk Kim 339dd962f5bSJung-uk Kim return (0); 340dd962f5bSJung-uk Kim } 341dd962f5bSJung-uk Kim 342dd962f5bSJung-uk Kim static int 343dd962f5bSJung-uk Kim scpm_suspend(device_t dev) 344dd962f5bSJung-uk Kim { 345dd962f5bSJung-uk Kim int error; 346dd962f5bSJung-uk Kim 347dd962f5bSJung-uk Kim error = bus_generic_suspend(dev); 348dd962f5bSJung-uk Kim if (error != 0) 349dd962f5bSJung-uk Kim return (error); 350dd962f5bSJung-uk Kim 351dd962f5bSJung-uk Kim return (scsuspend(dev)); 352dd962f5bSJung-uk Kim } 353dd962f5bSJung-uk Kim 354dd962f5bSJung-uk Kim static int 355dd962f5bSJung-uk Kim scpm_resume(device_t dev) 356dd962f5bSJung-uk Kim { 357dd962f5bSJung-uk Kim 358dd962f5bSJung-uk Kim scresume(dev); 359dd962f5bSJung-uk Kim 360dd962f5bSJung-uk Kim return (bus_generic_resume(dev)); 361dd962f5bSJung-uk Kim } 362dd962f5bSJung-uk Kim 363dd962f5bSJung-uk Kim static device_method_t scpm_methods[] = { 364dd962f5bSJung-uk Kim DEVMETHOD(device_identify, scpm_identify), 365dd962f5bSJung-uk Kim DEVMETHOD(device_probe, scpm_probe), 366dd962f5bSJung-uk Kim DEVMETHOD(device_attach, scpm_attach), 367dd962f5bSJung-uk Kim DEVMETHOD(device_suspend, scpm_suspend), 368dd962f5bSJung-uk Kim DEVMETHOD(device_resume, scpm_resume), 369dd962f5bSJung-uk Kim { 0, 0 } 370dd962f5bSJung-uk Kim }; 371dd962f5bSJung-uk Kim 372dd962f5bSJung-uk Kim static driver_t scpm_driver = { 373dd962f5bSJung-uk Kim "scpm", 374dd962f5bSJung-uk Kim scpm_methods, 375dd962f5bSJung-uk Kim 0 376dd962f5bSJung-uk Kim }; 377dd962f5bSJung-uk Kim 378dd962f5bSJung-uk Kim DRIVER_MODULE(scpm, vgapm, scpm_driver, scpm_devclass, 0, 0); 379