Home | History | Annotate | Download | only in modules
      1 /* ----------------------------------------------------------------------- *
      2  *
      3  *   Copyright 2013 Sebastian Herbszt - All Rights Reserved
      4  *
      5  *   This program is free software; you can redistribute it and/or modify
      6  *   it under the terms of the GNU General Public License as published by
      7  *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
      8  *   Boston MA 02110-1301, USA; either version 2 of the License, or
      9  *   (at your option) any later version; incorporated herein by reference.
     10  *
     11  * ----------------------------------------------------------------------- */
     12 
     13 /*
     14  * poweroff.c
     15  *
     16  * APM poweroff module
     17  */
     18 
     19 #include <stdio.h>
     20 #include <string.h>
     21 #include <com32.h>
     22 
     23 int main(int argc __unused, char *argv[] __unused)
     24 {
     25 	com32sys_t inregs, outregs;
     26 
     27 	memset(&inregs, 0, sizeof inregs);
     28 
     29 	inregs.eax.l = 0x5300; /* APM Installation Check (00h) */
     30 	inregs.ebx.l = 0; /* APM BIOS (0000h) */
     31 	__intcall(0x15, &inregs, &outregs);
     32 
     33 	if (outregs.eflags.l & EFLAGS_CF) {
     34 		printf("APM not present.\n");
     35 		return 1;
     36 	}
     37 
     38 	if ((outregs.ebx.l & 0xffff) != 0x504d) { /* signature 'PM' */
     39 		printf("APM not present.\n");
     40 		return 1;
     41 	}
     42 
     43 	if ((outregs.eax.l & 0xffff) < 0x101) { /* Need version 1.1+ */
     44 		printf("APM 1.1+ not supported.\n");
     45 		return 1;
     46 	}
     47 
     48 	if ((outregs.ecx.l & 0x8) == 0x8) { /* bit 3 APM BIOS Power Management disabled */
     49 		printf("Power management disabled.\n");
     50 		return 1;
     51 	}
     52 
     53 	memset(&inregs, 0, sizeof inregs);
     54 	inregs.eax.l = 0x5301; /* APM Real Mode Interface Connect (01h) */
     55 	inregs.ebx.l = 0; /* APM BIOS (0000h) */
     56 	__intcall(0x15, &inregs, &outregs);
     57 
     58 	if (outregs.eflags.l & EFLAGS_CF) {
     59 		printf("APM RM interface connect failed.\n");
     60 		return 1;
     61 	}
     62 
     63 	memset(&inregs, 0, sizeof inregs);
     64 	inregs.eax.l = 0x530e; /* APM Driver Version (0Eh) */
     65 	inregs.ebx.l = 0; /* APM BIOS (0000h) */
     66 	inregs.ecx.l = 0x101; /* APM Driver version 1.1 */
     67 	__intcall(0x15, &inregs, &outregs);
     68 
     69 	if (outregs.eflags.l & EFLAGS_CF) {
     70 		printf("APM 1.1+ not supported.\n");
     71 		return 1;
     72 	}
     73 
     74 	if ((outregs.ecx.l & 0xffff) < 0x101) { /* APM Connection version */
     75 		printf("APM 1.1+ not supported.\n");
     76 		return 1;
     77 	}
     78 
     79 	memset(&inregs, 0, sizeof inregs);
     80 	inregs.eax.l = 0x5307; /* Set Power State (07h) */
     81 	inregs.ebx.l = 1; /* All devices power managed by the APM BIOS */
     82 	inregs.ecx.l = 3; /* Power state off */
     83 	__intcall(0x15, &inregs, &outregs);
     84 
     85 	if (outregs.eflags.l & EFLAGS_CF) {
     86 		printf("Power off failed.\n");
     87 		return 1;
     88 	}
     89 
     90 	return 0;
     91 }
     92