patch-2.1.89 linux/drivers/char/apm_bios.c
Next file: linux/drivers/char/atarimouse.c
Previous file: linux/drivers/char/amigamouse.c
Back to the patch index
Back to the overall index
- Lines: 156
- Date:
Thu Feb 26 19:58:40 1998
- Orig file:
v2.1.88/linux/drivers/char/apm_bios.c
- Orig date:
Mon Feb 23 18:12:04 1998
diff -u --recursive --new-file v2.1.88/linux/drivers/char/apm_bios.c linux/drivers/char/apm_bios.c
@@ -27,6 +27,7 @@
* Version 1.0 and 1.1
* May 1996, Version 1.2
* Feb 1998, Version 1.3
+ * Feb 1998, Version 1.4
*
* History:
* 0.6b: first version in official kernel, Linux 1.3.46
@@ -46,8 +47,11 @@
* The new replacment for it is, but Linux doesn't yet support this.
* Alan Cox Linux 2.1.55
* 1.3: Set up a valid data descriptor 0x40 for buggy BIOS's
+ * 1.4: Upgraded to support APM 1.2. Integrated ThinkPad suspend patch by
+ * Dean Gaudet <dgaudet@arctic.org>.
+ * C. Scott Ananian <cananian@alumni.princeton.edu> Linux 2.1.87
*
- * Reference:
+ * APM 1.1 Reference:
*
* Intel Corporation, Microsoft Corporation. Advanced Power Management
* (APM) BIOS Interface Specification, Revision 1.1, September 1993.
@@ -58,6 +62,15 @@
* ftp://ftp.intel.com/pub/IAL/software_specs/apmv11.doc. It is also
* available from Microsoft by calling 206.882.8080.]
*
+ * APM 1.2 Reference:
+ * Intel Corporation, Microsoft Corporation. Advanced Power Management
+ * (APM) BIOS Interface Specification, Revision 1.2, February 1996.
+ *
+ * [This document is available from Intel at:
+ * http://www.intel.com/IAL/powermgm
+ * or Microsoft at
+ * http://www.microsoft.com/windows/thirdparty/hardware/pcfuture.htm
+ * ]
*/
#include <linux/config.h>
@@ -128,6 +141,11 @@
* problems have been reported when using this option with gpm (if you'd
* like to debug this, please do so).
*
+ * CONFIG_APM_IGNORE_MULTIPLE_SUSPEND: The IBM TP560 bios seems to insist
+ * on returning multiple suspend/standby events whenever one occurs. We
+ * really only need one at a time, so just ignore any beyond the first.
+ * This is probably safe on most laptops.
+ *
* If you are debugging the APM support for your laptop, note that code for
* all of these options is contained in this file, so you can #define or
* #undef these on the next line to avoid recompiling the whole kernel.
@@ -341,6 +359,9 @@
#endif
static int suspends_pending = 0;
static int standbys_pending = 0;
+#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
+static int waiting_for_resume = 0;
+#endif
static long clock_cmos_diff;
static int got_clock_diff = 0;
@@ -350,7 +371,7 @@
static struct timer_list apm_timer;
-static char driver_version[] = "1.3"; /* no spaces */
+static char driver_version[] = "1.4"; /* no spaces */
#ifdef APM_DEBUG
static char * apm_event_name[] = {
@@ -614,8 +635,15 @@
if (as == sender)
continue;
as->event_head = (as->event_head + 1) % APM_MAX_EVENTS;
- if (as->event_head == as->event_tail)
+ if (as->event_head == as->event_tail) {
+ static int notified;
+
+ if (notified == 0) {
+ printk( "apm_bios: an event queue overflowed\n" );
+ notified = 1;
+ }
as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
+ }
as->events[as->event_head] = event;
if (!as->suser)
continue;
@@ -722,9 +750,23 @@
apm_event_t event;
while ((event = get_event()) != 0) {
+#ifdef APM_DEBUG
+ if (event <= NR_APM_EVENT_NAME)
+ printk(KERN_DEBUG "APM BIOS received %s notify\n",
+ apm_event_name[event - 1]);
+ else
+ printk(KERN_DEBUG "APM BIOS received unknown "
+ "event 0x%02x\n", event);
+#endif
switch (event) {
case APM_SYS_STANDBY:
case APM_USER_STANDBY:
+#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
+ if (waiting_for_resume) {
+ return;
+ }
+ waiting_for_resume = 1;
+#endif
send_event(event, APM_STANDBY_RESUME, NULL);
if (standbys_pending <= 0)
standby();
@@ -737,6 +779,12 @@
break;
#endif
case APM_SYS_SUSPEND:
+#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
+ if (waiting_for_resume) {
+ return;
+ }
+ waiting_for_resume = 1;
+#endif
send_event(event, APM_NORMAL_RESUME, NULL);
if (suspends_pending <= 0)
suspend();
@@ -745,6 +793,9 @@
case APM_NORMAL_RESUME:
case APM_CRITICAL_RESUME:
case APM_STANDBY_RESUME:
+#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
+ waiting_for_resume = 0;
+#endif
set_time();
send_event(event, 0, NULL);
break;
@@ -763,14 +814,6 @@
suspend();
break;
}
-#ifdef APM_DEBUG
- if (event <= NR_APM_EVENT_NAME)
- printk(KERN_DEBUG "APM BIOS received %s notify\n",
- apm_event_name[event - 1]);
- else
- printk(KERN_DEBUG "APM BIOS received unknown event 0x%02x\n",
- event);
-#endif
}
}
@@ -905,7 +948,7 @@
as = fp->private_data;
if (check_apm_bios_struct(as, "select"))
return 0;
- poll_wait(&process_list, wait);
+ poll_wait(fp, &process_list, wait);
if (!queue_empty(as))
return POLLIN | POLLRDNORM;
return 0;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov