apm.c (41664) | apm.c (45720) |
---|---|
1/* 2 * APM (Advanced Power Management) BIOS Device Driver 3 * 4 * Copyright (c) 1994 UKAI, Fumitoshi. 5 * Copyright (c) 1994-1995 by HOSOKAWA, Tatsumi <hosokawa@jp.FreeBSD.org> 6 * Copyright (c) 1996 Nate Williams <nate@FreeBSD.org> 7 * Copyright (c) 1997 Poul-Henning Kamp <phk@FreeBSD.org> 8 * 9 * This software may be used, modified, copied, and distributed, in 10 * both source and binary form provided that the above copyright and 11 * these terms are retained. Under no circumstances is the author 12 * responsible for the proper functioning of this software, nor does 13 * the author assume any responsibility for damages incurred with its 14 * use. 15 * 16 * Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD) 17 * | 1/* 2 * APM (Advanced Power Management) BIOS Device Driver 3 * 4 * Copyright (c) 1994 UKAI, Fumitoshi. 5 * Copyright (c) 1994-1995 by HOSOKAWA, Tatsumi <hosokawa@jp.FreeBSD.org> 6 * Copyright (c) 1996 Nate Williams <nate@FreeBSD.org> 7 * Copyright (c) 1997 Poul-Henning Kamp <phk@FreeBSD.org> 8 * 9 * This software may be used, modified, copied, and distributed, in 10 * both source and binary form provided that the above copyright and 11 * these terms are retained. Under no circumstances is the author 12 * responsible for the proper functioning of this software, nor does 13 * the author assume any responsibility for damages incurred with its 14 * use. 15 * 16 * Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD) 17 * |
18 * $Id: apm.c,v 1.76 1998/12/04 21:28:39 archie Exp $ | 18 * $Id: apm.c,v 1.77 1998/12/10 23:36:14 msmith Exp $ |
19 */ 20 21#include "opt_devfs.h" 22#include "opt_vm86.h" 23 24#include <sys/param.h> 25#include <sys/conf.h> 26#include <sys/kernel.h> 27#ifdef DEVFS 28#include <sys/devfsext.h> 29#endif /*DEVFS*/ 30#include <sys/systm.h> 31#include <sys/time.h> 32#include <sys/reboot.h> | 19 */ 20 21#include "opt_devfs.h" 22#include "opt_vm86.h" 23 24#include <sys/param.h> 25#include <sys/conf.h> 26#include <sys/kernel.h> 27#ifdef DEVFS 28#include <sys/devfsext.h> 29#endif /*DEVFS*/ 30#include <sys/systm.h> 31#include <sys/time.h> 32#include <sys/reboot.h> |
33#include <i386/isa/isa_device.h> | 33#include <sys/bus.h> |
34#include <machine/apm_bios.h> 35#include <machine/segments.h> 36#include <machine/clock.h> 37#include <vm/vm.h> 38#include <vm/vm_param.h> 39#include <vm/pmap.h> 40#include <sys/syslog.h> 41#include <i386/apm/apm_setup.h> --- 385 unchanged lines hidden (view full) --- 427 * Execute suspend and resume hook before and after sleep, respectively. 428 * 429 */ 430 431void 432apm_suspend(int state) 433{ 434 struct apm_softc *sc = &apm_softc; | 34#include <machine/apm_bios.h> 35#include <machine/segments.h> 36#include <machine/clock.h> 37#include <vm/vm.h> 38#include <vm/vm_param.h> 39#include <vm/pmap.h> 40#include <sys/syslog.h> 41#include <i386/apm/apm_setup.h> --- 385 unchanged lines hidden (view full) --- 427 * Execute suspend and resume hook before and after sleep, respectively. 428 * 429 */ 430 431void 432apm_suspend(int state) 433{ 434 struct apm_softc *sc = &apm_softc; |
435 int error; |
|
435 436 if (!sc) 437 return; 438 439 if (sc->initialized) { | 436 437 if (!sc) 438 return; 439 440 if (sc->initialized) { |
441 error = DEVICE_SUSPEND(root_bus); 442 if (error) 443 return; /* XXX no error reporting */ |
|
440 apm_execute_hook(hook[APM_HOOK_SUSPEND]); 441 if (apm_suspend_system(state) == 0) 442 apm_processevent(); 443 else 444 /* Failure, 'resume' the system again */ 445 apm_execute_hook(hook[APM_HOOK_RESUME]); 446 } 447} 448 449void 450apm_resume(void) 451{ 452 struct apm_softc *sc = &apm_softc; 453 454 if (!sc) 455 return; 456 | 444 apm_execute_hook(hook[APM_HOOK_SUSPEND]); 445 if (apm_suspend_system(state) == 0) 446 apm_processevent(); 447 else 448 /* Failure, 'resume' the system again */ 449 apm_execute_hook(hook[APM_HOOK_RESUME]); 450 } 451} 452 453void 454apm_resume(void) 455{ 456 struct apm_softc *sc = &apm_softc; 457 458 if (!sc) 459 return; 460 |
457 if (sc->initialized) | 461 if (sc->initialized) { 462 DEVICE_RESUME(root_bus); |
458 apm_execute_hook(hook[APM_HOOK_RESUME]); | 463 apm_execute_hook(hook[APM_HOOK_RESUME]); |
464 } |
|
459} 460 461 462/* get APM information */ 463static int 464apm_get_info(apm_info_t aip) 465{ 466 struct apm_softc *sc = &apm_softc; --- 151 unchanged lines hidden (view full) --- 618{ 619 struct apm_softc *sc = &apm_softc; 620 621 if (sc->initialized) 622 sc->always_halt_cpu = 0; 623} 624 625/* device driver definitions */ | 465} 466 467 468/* get APM information */ 469static int 470apm_get_info(apm_info_t aip) 471{ 472 struct apm_softc *sc = &apm_softc; --- 151 unchanged lines hidden (view full) --- 624{ 625 struct apm_softc *sc = &apm_softc; 626 627 if (sc->initialized) 628 sc->always_halt_cpu = 0; 629} 630 631/* device driver definitions */ |
626static int apmprobe (struct isa_device *); 627static int apmattach(struct isa_device *); 628struct isa_driver apmdriver = { apmprobe, apmattach, "apm" }; | |
629 630/* 631 * probe APM (dummy): 632 * 633 * APM probing routine is placed on locore.s and apm_init.S because 634 * this process forces the CPU to turn to real mode or V86 mode. 635 * Current version uses real mode, but in a future version, we want 636 * to use V86 mode in APM initialization. 637 * 638 * XXX If VM86 is defined, we do. 639 */ 640 641static int | 632 633/* 634 * probe APM (dummy): 635 * 636 * APM probing routine is placed on locore.s and apm_init.S because 637 * this process forces the CPU to turn to real mode or V86 mode. 638 * Current version uses real mode, but in a future version, we want 639 * to use V86 mode in APM initialization. 640 * 641 * XXX If VM86 is defined, we do. 642 */ 643 644static int |
642apmprobe(struct isa_device *dvp) | 645apm_probe(device_t dev) |
643{ 644#ifdef VM86 645 struct vm86frame vmf; 646 int i; 647#endif | 646{ 647#ifdef VM86 648 struct vm86frame vmf; 649 int i; 650#endif |
651 int flags; |
|
648 | 652 |
649 if ( dvp->id_unit > 0 ) { | 653 device_set_desc(dev, "APM BIOS"); 654 655 if ( device_get_unit(dev) > 0 ) { |
650 printf("apm: Only one APM driver supported.\n"); | 656 printf("apm: Only one APM driver supported.\n"); |
651 return 0; | 657 return ENXIO; |
652 } 653 | 658 } 659 |
660 if (resource_int_value("apm", 0, "flags", &flags) != 0) 661 flags = 0; 662 |
|
654#ifdef VM86 655 bzero(&vmf, sizeof(struct vm86frame)); /* safety */ 656 vmf.vmf_ax = (APM_BIOS << 8) | APM_INSTCHECK; 657 vmf.vmf_bx = 0; 658 if (((i = vm86_intcall(SYSTEM_BIOS, &vmf)) == 0) && 659 !(vmf.vmf_eflags & PSL_C) && 660 (vmf.vmf_bx == 0x504d)) { 661 --- 45 unchanged lines hidden (view full) --- 707 return 0; 708 case APMINI_NOT32BIT: 709 printf("apm: 32bit connection is not supported.\n"); 710 return 0; 711 case APMINI_CONNECTERR: 712 printf("apm: 32-bit connection error.\n"); 713 return 0; 714 } | 663#ifdef VM86 664 bzero(&vmf, sizeof(struct vm86frame)); /* safety */ 665 vmf.vmf_ax = (APM_BIOS << 8) | APM_INSTCHECK; 666 vmf.vmf_bx = 0; 667 if (((i = vm86_intcall(SYSTEM_BIOS, &vmf)) == 0) && 668 !(vmf.vmf_eflags & PSL_C) && 669 (vmf.vmf_bx == 0x504d)) { 670 --- 45 unchanged lines hidden (view full) --- 716 return 0; 717 case APMINI_NOT32BIT: 718 printf("apm: 32bit connection is not supported.\n"); 719 return 0; 720 case APMINI_CONNECTERR: 721 printf("apm: 32-bit connection error.\n"); 722 return 0; 723 } |
715 if (dvp->id_flags & 0x20) | 724 if (flags & 0x20) |
716 statclock_disable = 1; | 725 statclock_disable = 1; |
717 return -1; | 726 return 0; |
718} 719 720 721/* Process APM event */ 722static void 723apm_processevent(void) 724{ 725 int apm_event; --- 48 unchanged lines hidden (view full) --- 774 775/* 776 * Attach APM: 777 * 778 * Initialize APM driver (APM BIOS itself has been initialized in locore.s) 779 */ 780 781static int | 727} 728 729 730/* Process APM event */ 731static void 732apm_processevent(void) 733{ 734 int apm_event; --- 48 unchanged lines hidden (view full) --- 783 784/* 785 * Attach APM: 786 * 787 * Initialize APM driver (APM BIOS itself has been initialized in locore.s) 788 */ 789 790static int |
782apmattach(struct isa_device *dvp) | 791apm_attach(device_t dev) |
783{ 784#define APM_KERNBASE KERNBASE 785 struct apm_softc *sc = &apm_softc; | 792{ 793#define APM_KERNBASE KERNBASE 794 struct apm_softc *sc = &apm_softc; |
795 int flags; |
|
786 | 796 |
797 if (resource_int_value("apm", 0, "flags", &flags) != 0) 798 flags = 0; 799 |
|
787 sc->initialized = 0; 788 789 /* Must be externally enabled */ 790 sc->active = 0; 791 792 /* setup APM parameters */ 793 sc->cs16_base = (apm_cs16_base << 4) + APM_KERNBASE; 794 sc->cs32_base = (apm_cs32_base << 4) + APM_KERNBASE; --- 33 unchanged lines hidden (view full) --- 828 /* setup GDT */ 829 setup_apm_gdt(sc->cs32_base, sc->cs16_base, sc->ds_base, 830 sc->cs32_limit, sc->cs16_limit, sc->ds_limit); 831 832 /* setup entry point 48bit pointer */ 833 apm_addr.segment = GSEL(GAPMCODE32_SEL, SEL_KPL); 834 apm_addr.offset = sc->cs_entry; 835 | 800 sc->initialized = 0; 801 802 /* Must be externally enabled */ 803 sc->active = 0; 804 805 /* setup APM parameters */ 806 sc->cs16_base = (apm_cs16_base << 4) + APM_KERNBASE; 807 sc->cs32_base = (apm_cs32_base << 4) + APM_KERNBASE; --- 33 unchanged lines hidden (view full) --- 841 /* setup GDT */ 842 setup_apm_gdt(sc->cs32_base, sc->cs16_base, sc->ds_base, 843 sc->cs32_limit, sc->cs16_limit, sc->ds_limit); 844 845 /* setup entry point 48bit pointer */ 846 apm_addr.segment = GSEL(GAPMCODE32_SEL, SEL_KPL); 847 apm_addr.offset = sc->cs_entry; 848 |
836 if ((dvp->id_flags & 0x10)) { 837 if ((dvp->id_flags & 0xf) >= 0x2) { | 849 if ((flags & 0x10)) { 850 if ((flags & 0xf) >= 0x2) { |
838 apm_driver_version(0x102); 839 } | 851 apm_driver_version(0x102); 852 } |
840 if (!apm_version && (dvp->id_flags & 0xf) >= 0x1) { | 853 if (!apm_version && (flags & 0xf) >= 0x1) { |
841 apm_driver_version(0x101); 842 } 843 } else { 844 apm_driver_version(0x102); 845 if (!apm_version) 846 apm_driver_version(0x101); 847 } 848 if (!apm_version) --- 155 unchanged lines hidden (view full) --- 1004 break; 1005 default: 1006 error = EINVAL; 1007 break; 1008 } 1009 return error; 1010} 1011 | 854 apm_driver_version(0x101); 855 } 856 } else { 857 apm_driver_version(0x102); 858 if (!apm_version) 859 apm_driver_version(0x101); 860 } 861 if (!apm_version) --- 155 unchanged lines hidden (view full) --- 1017 break; 1018 default: 1019 error = EINVAL; 1020 break; 1021 } 1022 return error; 1023} 1024 |
1025static device_method_t apm_methods[] = { 1026 /* Device interface */ 1027 DEVMETHOD(device_probe, apm_probe), 1028 DEVMETHOD(device_attach, apm_attach), |
|
1012 | 1029 |
1013static apm_devsw_installed = 0; | 1030 { 0, 0 } 1031}; |
1014 | 1032 |
1015static void 1016apm_drvinit(void *unused) 1017{ 1018 dev_t dev; | 1033static driver_t apm_driver = { 1034 "apm", 1035 apm_methods, 1036 DRIVER_TYPE_MISC, 1037 1, /* no softc (XXX) */ 1038}; |
1019 | 1039 |
1020 if( ! apm_devsw_installed ) { 1021 dev = makedev(CDEV_MAJOR,0); 1022 cdevsw_add(&dev,&apm_cdevsw,NULL); 1023 apm_devsw_installed = 1; 1024 } 1025} | 1040static devclass_t apm_devclass; |
1026 | 1041 |
1027SYSINIT(apmdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,apm_drvinit,NULL) | 1042CDEV_DRIVER_MODULE(apm, nexus, apm_driver, apm_devclass, 1043 CDEV_MAJOR, apm_cdevsw, 0, 0); |