1 /* 2 * APM BIOS utility for FreeBSD 3 * 4 * Copyright (C) 1994-1996 by Tatsumi Hosokawa <hosokawa@jp.FreeBSD.org> 5 * 6 * This software may be used, modified, copied, distributed, and sold, 7 * in both source and binary form provided that the above copyright and 8 * these terms are retained. Under no circumstances is the author 9 * responsible for the proper functioning of this software, nor does 10 * the author assume any responsibility for damages incurred with its 11 * use. 12 * 13 * Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD) 14 */ 15 16 #include <sys/ioctl.h> 17 18 #include <machine/apm_bios.h> 19 20 #include <err.h> 21 #include <fcntl.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <unistd.h> 26 27 #define APMDEV "/dev/apm" 28 29 #define APM_UNKNOWN 255 30 31 static void 32 usage(void) 33 { 34 fprintf(stderr, 35 "usage: apm [-abltzZ]\n"); 36 exit(1); 37 } 38 39 static void 40 apm_suspend(int fd) 41 { 42 if (ioctl(fd, APMIO_SUSPEND, NULL) == -1) 43 err(1, "ioctl(APMIO_SUSPEND)"); 44 } 45 46 static void 47 apm_standby(int fd) 48 { 49 if (ioctl(fd, APMIO_STANDBY, NULL) == -1) 50 err(1, "ioctl(APMIO_STANDBY)"); 51 } 52 53 static void 54 apm_getinfo(int fd, apm_info_t aip) 55 { 56 if (ioctl(fd, APMIO_GETINFO, aip) == -1) 57 err(1, "ioctl(APMIO_GETINFO)"); 58 } 59 60 static void 61 print_batt_time(int batt_time) 62 { 63 printf("Remaining battery time: "); 64 if (batt_time == -1) 65 printf("unknown\n"); 66 else { 67 int h, m, s; 68 69 h = batt_time; 70 s = h % 60; 71 h /= 60; 72 m = h % 60; 73 h /= 60; 74 printf("%2d:%02d:%02d\n", h, m, s); 75 } 76 } 77 78 static void 79 print_batt_life(u_int batt_life) 80 { 81 printf("Remaining battery life: "); 82 if (batt_life == APM_UNKNOWN) 83 printf("unknown\n"); 84 else if (batt_life <= 100) 85 printf("%d%%\n", batt_life); 86 else 87 printf("invalid value (0x%x)\n", batt_life); 88 } 89 90 static void 91 print_batt_stat(u_int batt_stat) 92 { 93 const char *batt_msg[] = { "high", "low", "critical", "charging" }; 94 95 printf("Battery Status: "); 96 if (batt_stat == APM_UNKNOWN) 97 printf("unknown\n"); 98 else if (batt_stat > 3) 99 printf("invalid value (0x%x)\n", batt_stat); 100 else 101 printf("%s\n", batt_msg[batt_stat]); 102 } 103 104 static void 105 print_all_info(int fd, apm_info_t aip) 106 { 107 const char *line_msg[] = { "off-line", "on-line" , "backup power"}; 108 109 printf("APM version: %d.%d\n", aip->ai_major, aip->ai_minor); 110 printf("APM Management: %s\n", aip->ai_status ? "Enabled" : "Disabled"); 111 printf("AC Line status: "); 112 if (aip->ai_acline == APM_UNKNOWN) 113 printf("unknown\n"); 114 else if (aip->ai_acline > 2) 115 printf("invalid value (0x%x)\n", aip->ai_acline); 116 else 117 printf("%s\n", line_msg[aip->ai_acline]); 118 119 print_batt_stat(aip->ai_batt_stat); 120 print_batt_life(aip->ai_batt_life); 121 print_batt_time(aip->ai_batt_time); 122 123 if (aip->ai_infoversion >= 1) { 124 printf("Number of batteries: "); 125 if (aip->ai_batteries == ~0U) 126 printf("unknown\n"); 127 else { 128 u_int i; 129 struct apm_pwstatus aps; 130 131 printf("%d\n", aip->ai_batteries); 132 for (i = 0; i < aip->ai_batteries; ++i) { 133 bzero(&aps, sizeof(aps)); 134 aps.ap_device = PMDV_BATT0 + i; 135 if (ioctl(fd, APMIO_GETPWSTATUS, &aps) == -1) 136 continue; 137 printf("Battery %d:\n", i); 138 if (aps.ap_batt_flag & APM_BATT_NOT_PRESENT) { 139 printf("not present\n"); 140 continue; 141 } 142 printf("\t"); 143 print_batt_stat(aps.ap_batt_stat); 144 printf("\t"); 145 print_batt_life(aps.ap_batt_life); 146 printf("\t"); 147 print_batt_time(aps.ap_batt_time); 148 } 149 } 150 } 151 152 if (aip->ai_infoversion >= 1) { 153 if (aip->ai_capabilities == 0xff00) 154 return; 155 printf("APM Capabilities:\n"); 156 if (aip->ai_capabilities & 0x01) 157 printf("\tglobal standby state\n"); 158 if (aip->ai_capabilities & 0x02) 159 printf("\tglobal suspend state\n"); 160 if (aip->ai_capabilities & 0x04) 161 printf("\tresume timer from standby\n"); 162 if (aip->ai_capabilities & 0x08) 163 printf("\tresume timer from suspend\n"); 164 if (aip->ai_capabilities & 0x10) 165 printf("\tRI resume from standby\n"); 166 if (aip->ai_capabilities & 0x20) 167 printf("\tRI resume from suspend\n"); 168 if (aip->ai_capabilities & 0x40) 169 printf("\tPCMCIA RI resume from standby\n"); 170 if (aip->ai_capabilities & 0x80) 171 printf("\tPCMCIA RI resume from suspend\n"); 172 } 173 174 } 175 176 int 177 main(int argc, char *argv[]) 178 { 179 int c, fd; 180 int dosleep = 0, all_info = 1, batt_status = 0; 181 int batt_life = 0, ac_status = 0, standby = 0; 182 int batt_time = 0; 183 184 while ((c = getopt(argc, argv, "abltzZ")) != -1) { 185 switch (c) { 186 case 'a': 187 ac_status = 1; 188 all_info = 0; 189 break; 190 case 'b': 191 batt_status = 1; 192 all_info = 0; 193 break; 194 case 'l': 195 batt_life = 1; 196 all_info = 0; 197 break; 198 case 't': 199 batt_time = 1; 200 all_info = 0; 201 break; 202 case 'z': 203 dosleep = 1; 204 all_info = 0; 205 break; 206 case 'Z': 207 standby = 1; 208 all_info = 0; 209 break; 210 case '?': 211 default: 212 usage(); 213 } 214 argc -= optind; 215 argv += optind; 216 } 217 if (dosleep || standby) 218 fd = open(APMDEV, O_RDWR); 219 else 220 fd = open(APMDEV, O_RDONLY); 221 if (fd == -1) 222 err(1, "can't open %s", APMDEV); 223 if (dosleep) 224 apm_suspend(fd); 225 else if (standby) 226 apm_standby(fd); 227 else { 228 struct apm_info info; 229 230 apm_getinfo(fd, &info); 231 if (all_info) 232 print_all_info(fd, &info); 233 if (ac_status) 234 printf("%d\n", info.ai_acline); 235 if (batt_status) 236 printf("%d\n", info.ai_batt_stat); 237 if (batt_life) 238 printf("%d\n", info.ai_batt_life); 239 if (batt_time) 240 printf("%d\n", info.ai_batt_time); 241 } 242 close(fd); 243 exit(0); 244 } 245