patch-1.3.58 linux/drivers/char/apm_bios.c
Next file: linux/drivers/char/keyboard.c
Previous file: linux/drivers/char/Makefile
Back to the patch index
Back to the overall index
- Lines: 219
- Date:
Sun Jan 14 19:08:31 1996
- Orig file:
v1.3.57/linux/drivers/char/apm_bios.c
- Orig date:
Mon Dec 11 15:42:02 1995
diff -u --recursive --new-file v1.3.57/linux/drivers/char/apm_bios.c linux/drivers/char/apm_bios.c
@@ -1,4 +1,4 @@
-/*
+/* -*- linux-c -*-
* APM BIOS driver for Linux
* Copyright 1994, 1995 Stephen Rothwell (Stephen.Rothwell@pd.necisa.oz.au)
*
@@ -16,6 +16,10 @@
*
* October 1995, Rik Faith (faith@cs.unc.edu):
* Minor enhancements and updates (to the patch set) for 1.3.x
+ * Documentation
+ * January 1996, Rik Faith (faith@cs.unc.edu):
+ * Make /proc/apm easy to format (bump driver version)
+ *
*
* Reference:
*
@@ -24,9 +28,9 @@
* Intel Order Number 241704-001. Microsoft Part Number 781-110-X01.
*
* [This document is available free from Intel by calling 800.628.8686 (fax
- * 916.356.6100) or 800.548.4725. It is also available from Microsoft by
- * calling 206.882.8080; and is ftpable from
- * ftp://ftp.intel.com/pub/IAL/software_specs/apmv11.doc]
+ * 916.356.6100) or 800.548.4725; or via anonymous ftp from
+ * ftp://ftp.intel.com/pub/IAL/software_specs/apmv11.doc. It is also
+ * available from Microsoft by calling 206.882.8080.]
*
*/
@@ -288,7 +292,7 @@
static struct timer_list apm_timer;
-static char driver_version[] = "0.6b";
+static char driver_version[] = "0.7";/* no spaces */
#ifdef APM_DEBUG
static char * apm_event_name[] = {
@@ -882,69 +886,91 @@
int apm_proc(char *buf)
{
char * p;
- char * power_stat;
- char * bat_stat;
unsigned short bx;
unsigned short cx;
unsigned short dx;
unsigned short error;
+ unsigned short ac_line_status = 0xff;
+ unsigned short battery_status = 0xff;
+ unsigned short battery_flag = 0xff;
+ unsigned short percentage = -1;
+ int time_units = -1;
+ char *units = "?";
if (apm_bios_info.version == 0)
return 0;
p = buf;
- p += sprintf(p, "BIOS version: %d.%d\nFlags: 0x%02x\n",
- (apm_bios_info.version >> 8) & 0xff,
- apm_bios_info.version & 0xff,
- apm_bios_info.flags);
- if ((apm_bios_info.flags & APM_32_BIT_SUPPORT) == 0)
- return p - buf;
- p += sprintf(p, "Entry %x:%lx cseg16 %x dseg %x",
- apm_bios_info.cseg, apm_bios_info.offset,
- apm_bios_info.cseg_16, apm_bios_info.dseg);
- if (apm_bios_info.version > 0x100)
- p += sprintf(p, " cseg len %x, dseg len %x",
- apm_bios_info.cseg_len, apm_bios_info.dseg_len);
- *p++ = '\n';
- error = apm_get_power_status(&bx, &cx, &dx);
- if (error) {
- strcpy(p, "Power status not available\n");
- p += strlen(p);
- return p - buf;
- }
- switch ((bx >> 8) & 0xff) {
- case 0: power_stat = "off line"; break;
- case 1: power_stat = "on line"; break;
- case 2: power_stat = "on backup power"; break;
- default: power_stat = "unknown"; break;
- }
- switch (bx & 0xff) {
- case 0: bat_stat = "high"; break;
- case 1: bat_stat = "low"; break;
- case 2: bat_stat = "critical"; break;
- case 3: bat_stat = "charging"; break;
- default: bat_stat = "unknown"; break;
- }
- p += sprintf(p, "AC: %s\nBattery status: %s\nBattery life: ",
- power_stat, bat_stat);
- if ((cx & 0xff) == 0xff) {
- strcpy(p, "unknown");
- p += strlen(p);
- } else
- p += sprintf(p, "%d%%", cx & 0xff);
- *p++ = '\n';
- if (apm_bios_info.version > 0x100) {
- p += sprintf(p, "Battery flag: 0x%02x\nBattery life: ",
- (cx >> 8) & 0xff);
- if (dx == 0xffff) {
- strcpy(p, "unknown");
- p += strlen(p);
+
+ if ((apm_bios_info.flags & APM_32_BIT_SUPPORT) != 0) {
+ if (!(error = apm_get_power_status(&bx, &cx, &dx))) {
+ ac_line_status = (bx >> 8) & 0xff;
+ battery_status = bx & 0xff;
+ if ((cx & 0xff) != 0xff)
+ percentage = cx & 0xff;
+
+ if (apm_bios_info.version > 0x100) {
+ battery_flag = (cx >> 8) & 0xff;
+ if (dx != 0xffff) {
+ if ((dx & 0x8000) == 0x8000) {
+ units = "min";
+ time_units = dx & 0x7ffe;
+ } else {
+ units = "sec";
+ time_units = dx & 0x7fff;
+ }
+ }
+ }
}
- else
- p += sprintf(p, "%d %s", dx & 0x7fff,
- ((dx & 0x8000) == 0)
- ? "seconds" : "minutes");
- *p++ = '\n';
}
+ /* Arguments, with symbols from linux/apm_bios.h. Information is
+ from the Get Power Status (0x0a) call unless otherwise noted.
+
+ 0) Linux driver version (this will change if format changes)
+ 1) APM BIOS Version. Usually 1.0 or 1.1.
+ 2) APM flags from APM Installation Check (0x00):
+ bit 0: APM_16_BIT_SUPPORT
+ bit 1: APM_32_BIT_SUPPORT
+ bit 2: APM_IDLE_SLOWS_CLOCK
+ bit 3: APM_BIOS_DISABLED
+ bit 4: APM_BIOS_DISENGAGED
+ 3) AC line status
+ 0x00: Off-line
+ 0x01: On-line
+ 0x02: On backup power (APM BIOS 1.1 only)
+ 0xff: Unknown
+ 4) Battery status
+ 0x00: High
+ 0x01: Low
+ 0x02: Critical
+ 0x03: Charging
+ 0xff: Unknown
+ 5) Battery flag
+ bit 0: High
+ bit 1: Low
+ bit 2: Critical
+ bit 3: Charging
+ bit 7: No system battery
+ 0xff: Unknown
+ 6) Remaining battery life (percentage of charge):
+ 0-100: valid
+ -1: Unknown
+ 7) Remaining battery life (time units):
+ Number of remaining minutes or seconds
+ -1: Unknown
+ 8) min = minutes; sec = seconds */
+
+ p += sprintf(p, "%s %d.%d 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
+ driver_version,
+ (apm_bios_info.version >> 8) & 0xff,
+ apm_bios_info.version & 0xff,
+ apm_bios_info.flags,
+ ac_line_status,
+ battery_status,
+ battery_flag,
+ percentage,
+ time_units,
+ units );
+
return p - buf;
}
@@ -1000,12 +1026,12 @@
set_limit(gdt[APM_DS >> 3], 64 * 1024);
} else {
set_limit(gdt[APM_CS >> 3], apm_bios_info.cseg_len);
- /*
- * This is not clear from the spec, but at least one
- * machine needs this to be a 64k segment.
- */
+ /* This is not clear from the spec, but at least one
+ machine needs CS_16 to be a 64k segment, and the DEC
+ Hinote Ultra CT475 (and others?) needs DS to be a 64k
+ segment. */
set_limit(gdt[APM_CS_16 >> 3], 64 * 1024);
- set_limit(gdt[APM_DS >> 3], apm_bios_info.dseg_len);
+ set_limit(gdt[APM_DS >> 3], 64 * 1024);
apm_bios_info.version = 0x0101;
error = apm_driver_version(&apm_bios_info.version);
if (error != 0)
@@ -1047,10 +1073,12 @@
(cx >> 8) & 0xff);
if (dx == 0xffff)
printk("unknown\n");
- else
- printk("%d %s\n", dx & 0x7fff,
- ((dx & 0x8000) == 0)
- ? "seconds" : "minutes");
+ else {
+ if ((dx & 0x8000))
+ printk("%d minutes\n", dx & 0x7ffe );
+ else
+ printk("%d seconds\n", dx & 0x7fff );
+ }
}
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this