public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* kernel apm code
@ 2001-03-27 14:40 David Balazic
  2001-03-27 19:06 ` John Fremlin
       [not found] ` <"m28zlr58w9.fsf"@boreas.yi.org>
  0 siblings, 2 replies; 5+ messages in thread
From: David Balazic @ 2001-03-27 14:40 UTC (permalink / raw)
  To: linux-kernel@vger.kernel.org, linux-laptop, apm, apenwarr, sfr

The current kernel ( 2.4.2-ac26 or 2.4.3-pre8 ) has 
arch/i386/kernel/apm.c version 1.14 while version 1.15
is available as a patch to 2.3.99-pre7-1  ( read :
it was available for ages ) at http://linuxcare.com.au/apm/

The newer version has among other things support for
the APM_IOC_REJECT ioctl which is useful for example
when implementing "run /sbin/shutdown -h when the power
button is pressed".

While isn't this merged into the official kernel ?

Is apm.c v1.15 the latest ?
The last modification of the http://linuxcare.com.au/apm/ page
was in may 2000 and in 2.4.2-ac25 the web address for the APM driver
was changed to http://www.canb.auug.org.au/~sfr/ , but that page
doesn't have much/any content about the APM driver.


On a related note :
Both Abit BH6 and MSI K7T Pro2A send a SYSTEM_SUSPEND APM event
( APM_SYS_SUSPEND ) when I press the power button. When the OS
acknowledges the event, the system doesn't go to suspend , as
the OS expects , but to power-off , killing all running processes
and causing an unclean umount , among other things.

Is this the APM standard behavior or do I have two weird motherboards ?


P.S.: Looking for an archive of the linux-laptop@vger.kernel.org
mail list.

-- 
David Balazic
--------------
"Be excellent to each other." - Bill & Ted
- - - - - - - - - - - - - - - - - - - - - -

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: kernel apm code
  2001-03-27 14:40 kernel apm code David Balazic
@ 2001-03-27 19:06 ` John Fremlin
       [not found] ` <"m28zlr58w9.fsf"@boreas.yi.org>
  1 sibling, 0 replies; 5+ messages in thread
From: John Fremlin @ 2001-03-27 19:06 UTC (permalink / raw)
  To: David Balazic
  Cc: linux-kernel@vger.kernel.org, linux-laptop, apm, apenwarr, sfr

[-- Attachment #1: Type: text/plain, Size: 599 bytes --]

 David Balazic <david.balazic@uni-mb.si> writes:

> The newer version has among other things support for
> the APM_IOC_REJECT ioctl which is useful for example
> when implementing "run /sbin/shutdown -h when the power
> button is pressed".
> 
> While isn't this merged into the official kernel ?

The maintainer hasn't the time to do it. He promised me he would in
February, when I telephone, but hasn't bothered to do anything
AFAICS. I hacked together the following patch for it a while ago,
which updated APM_IOC_REJECT for slightly more recent kernels (be
warned, I think I made some mistakes)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: linux-2.4.0-test13-pre4-apm-reject.patch --]
[-- Type: text/x-patch, Size: 5050 bytes --]

diff -u linux-2.4.0-test13-pre4/arch/i386/kernel/apm.c linux-hacked/arch/i386/kernel/apm.c
--- linux-2.4.0-test13-pre4/arch/i386/kernel/apm.c	Fri Dec 29 22:47:16 2000
+++ linux-hacked/arch/i386/kernel/apm.c	Fri Dec 29 22:49:32 2000
@@ -38,6 +38,7 @@
  * Jan 2000, Version 1.12
  * Feb 2000, Version 1.13
  * Nov 2000, Version 1.14
+ * Dec 2000, Version 1.15
  *
  * History:
  *    0.6b: first version in official kernel, Linux 1.3.46
@@ -148,6 +149,10 @@
  *   1.14: Make connection version persist across module unload/load.
  *         Enable and engage power management earlier.
  *         Disengage power management on module unload.
+ *   1.15: Add APM_IOC_REJECT ioctl, based on a patch from Stephen
+ *         Rothwell but apparently written by Craig Markwardt
+ *         <craigm@lheamail.gsfc.nasa.gov>.
+ *         John Fremlin <vii@penguinpowered.com>
  *
  * APM 1.1 Reference:
  *
@@ -301,6 +306,7 @@
 	int		suspend_result;
 	int		suspends_pending;
 	int		standbys_pending;
+	int		rejects_pending;
 	int		suspends_read;
 	int		standbys_read;
 	int		event_head;
@@ -325,6 +331,7 @@
 #endif
 static int			suspends_pending;
 static int			standbys_pending;
+static int			rejects_pending;
 static int			waiting_for_resume;
 static int			ignore_normal_resume;
 static int			bounce_interval = DEFAULT_BOUNCE_INTERVAL;
@@ -350,7 +357,7 @@
 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
 static struct apm_user *	user_list;
 
-static char			driver_version[] = "1.14";	/* no spaces */
+static char			driver_version[] = "1.15";	/* no spaces */
 
 static char *	apm_event_name[] = {
 	"system standby",
@@ -832,6 +839,15 @@
 			as->standbys_pending++;
 			standbys_pending++;
 			break;
+
+		case APM_SUSPEND_REJECT:
+			as->suspend_wait = 0;
+			as->suspend_result = -EAGAIN;
+			/* Fall through to */
+		case APM_STANDBY_REJECT:
+			as->rejects_pending++;
+			rejects_pending++;
+			break;
 		}
 	}
 	wake_up_interruptible(&apm_waitqueue);
@@ -1211,6 +1227,41 @@
 	return 0;
 }
 
+static int send_reject(struct apm_user *as, apm_event_t state)
+{
+	if (as->rejects_pending > 0) {
+		as->rejects_pending--;
+		rejects_pending--;
+	} else {
+		switch (state) {
+		case APM_SYS_SUSPEND:
+		case APM_USER_SUSPEND:
+			queue_event(APM_SUSPEND_REJECT, as);
+			break;
+		case APM_SYS_STANDBY:
+		case APM_USER_STANDBY:
+			queue_event(APM_STANDBY_REJECT, as);
+			break;
+		}
+	}
+	if ((rejects_pending <= 0) &&
+	    (suspends_pending <= 0) &&
+	    (standbys_pending <= 0)) {
+		switch (state) {
+		case APM_SYS_SUSPEND:
+		case APM_USER_SUSPEND:
+			send_event(APM_NORMAL_RESUME);
+			break;
+		case APM_SYS_STANDBY:
+		case APM_USER_STANDBY:
+			send_event(APM_STANDBY_RESUME);
+			break;
+		}
+		return apm_set_power_state(APM_STATE_REJECT);
+	}
+	return APM_SUCCESS;
+}
+
 static int do_ioctl(struct inode * inode, struct file *filp,
 		    u_int cmd, u_long arg)
 {
@@ -1262,12 +1313,30 @@
 			return as->suspend_result;
 		}
 		break;
+	case APM_IOC_REJECT:
+		if (as->suspends_read > 0) {
+			as->suspends_read--;
+			as->suspends_pending--;
+			suspends_pending--;
+			if(send_reject(as, APM_SYS_SUSPEND)!=APM_SUCCESS)
+				return -EREMOTEIO;
+		} else if (as->standbys_read > 0) {
+			as->standbys_read--;
+			as->standbys_pending--;
+			standbys_pending--;
+			if(send_reject(as, APM_SYS_STANDBY)!=APM_SUCCESS)
+				return -EREMOTEIO;
+		} else
+			return -EINVAL;
+		break;
 	default:
 		return -EINVAL;
 	}
 	return 0;
 }
 
+
+
 static int do_release(struct inode * inode, struct file * filp)
 {
 	struct apm_user *	as;
@@ -1277,14 +1346,16 @@
 		return 0;
 	filp->private_data = NULL;
 	lock_kernel();
+	rejects_pending -= as->rejects_pending;
+	as->rejects_pending = 0;
 	if (as->standbys_pending > 0) {
 		standbys_pending -= as->standbys_pending;
-		if (standbys_pending <= 0)
+		if (standbys_pending <= 0 && rejects_pending <= 0)
 			standby();
 	}
 	if (as->suspends_pending > 0) {
 		suspends_pending -= as->suspends_pending;
-		if (suspends_pending <= 0)
+		if (suspends_pending <= 0 && rejects_pending <= 0)
 			(void) suspend();
 	}
 	if (user_list == as)
@@ -1318,7 +1389,7 @@
 	}
 	as->magic = APM_BIOS_MAGIC;
 	as->event_tail = as->event_head = 0;
-	as->suspends_pending = as->standbys_pending = 0;
+	as->suspends_pending = as->standbys_pending = as->rejects_pending = 0;
 	as->suspends_read = as->standbys_read = 0;
 	/*
 	 * XXX - this is a tiny bit broken, when we consider BSD
diff --recursive -u linux-2.4.0-test13-pre4/include/linux/apm_bios.h linux-hacked/include/linux/apm_bios.h
--- linux-2.4.0-test13-pre4/include/linux/apm_bios.h	Fri Dec 29 22:46:31 2000
+++ linux-hacked/include/linux/apm_bios.h	Fri Dec 29 06:57:09 2000
@@ -139,6 +139,8 @@
 #define APM_USER_SUSPEND	0x000a
 #define APM_STANDBY_RESUME	0x000b
 #define APM_CAPABILITY_CHANGE	0x000c
+#define APM_STANDBY_REJECT	0x000d
+#define APM_SUSPEND_REJECT	0x000e
 
 /*
  * Error codes
@@ -210,5 +212,6 @@
 
 #define APM_IOC_STANDBY		_IO('A', 1)
 #define APM_IOC_SUSPEND		_IO('A', 2)
+#define APM_IOC_REJECT		_IO('A', 3)
 
 #endif	/* LINUX_APM_H */

[-- Attachment #3: Type: text/plain, Size: 660 bytes --]


I made a (IMHO) better version called pmpolicy, based on different
principles. More information is available at

        http://john.snoop.dk/programs/linux/offbutton/

The most recent version of the patch (for 2.4.2) is not yet uploaded
however - mail me if you want it. It has not been included in the
kernel, because the APM maintainer Stephen Rothwell didn't like the
idea of me implementing it, as some people at linuxcare (including
Stephen) want to do it differently themselves. However this
"political" reason aside, Alan Cox says it changes too much for a
stable release so I guess it's not going in.

[...]

-- 

	http://www.penguinpowered.com/~vii

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: kernel apm code
       [not found]     ` <"m2bsqmlyrh.fsf"@boreas.yi.org>
@ 2001-03-29  9:25       ` David Balazic
  2001-03-29 16:44         ` John Fremlin
       [not found]         ` <"m24rwcjziu.fsf"@boreas.yi.org>
  0 siblings, 2 replies; 5+ messages in thread
From: David Balazic @ 2001-03-29  9:25 UTC (permalink / raw)
  To: John Fremlin
  Cc: linux-kernel@vger.kernel.org, linux-laptop, apm, apenwarr, sfr

John Fremlin wrote:
> 
> David Balazic <david.balazic@uni-mb.si> writes:
> 
> > John Fremlin wrote:
> > >
> > >  David Balazic <david.balazic@uni-mb.si> writes:
> 
> [...]
> 
> > > The maintainer hasn't the time to do it. He promised me he would in
> > > February, when I telephone, but hasn't bothered to do anything
> > > AFAICS. I hacked together the following patch for it a while ago,
> > > which updated APM_IOC_REJECT for slightly more recent kernels (be
> > > warned, I think I made some mistakes)
> >
> > It uses the same version number ( 1.15 ) as the "official" apm.c (
> > at linuxcare.com.au/apm ). I don't think that is a good idea.  Maybe
> > 1.14b ?
> 
> Well it's not going to go anywhere unless you want to look after it so
> there's not much point in worrying about that :-)

And the 2.4.2-ac26 apm.c has version 1.14 changes listed that are different
from the 1.14. changes listed in the patch from linuxcare.com.au/apm,
so it is not as big problem as I thought.

> [...]
> 
> > > I made a (IMHO) better version called pmpolicy, based on different
> > > principles. More information is available at
> > >
> > >         http://john.snoop.dk/programs/linux/offbutton/
> 
> > To implement off-button you only need the APM_IOC_REJECT ioctl and
> 
> The problem on my computer with my (re)implementation of
> APM_IOC_REJECT is that the screen goes into powersaving when the user
> suspend is received, then turns it back on when APM_IOC_REJECT is sent
> by apmd.

What is wrong with that ?
Suspend is requested -> suspend is executed
Suspend is canceled (rejected) -> suspend is canceled

Seems perfectly OK to me.


> Stephen said this was something wrong with my implementation
> (???).

User error ? :-)

> Anyway it is fixed in my pmpolicy patch, and I don't need no
> daemon so the code is a lot cleaner and simpler (no binary magic
> number interfaces).

But there should be no policy in the kernel ! ;-)

-- 
David Balazic
--------------
"Be excellent to each other." - Bill & Ted
- - - - - - - - - - - - - - - - - - - - - -

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: kernel apm code
  2001-03-29  9:25       ` David Balazic
@ 2001-03-29 16:44         ` John Fremlin
       [not found]         ` <"m24rwcjziu.fsf"@boreas.yi.org>
  1 sibling, 0 replies; 5+ messages in thread
From: John Fremlin @ 2001-03-29 16:44 UTC (permalink / raw)
  To: David Balazic
  Cc: linux-kernel@vger.kernel.org, linux-laptop, apm, apenwarr, sfr

 David Balazic <david.balazic@uni-mb.si> writes:

> John Fremlin wrote:

[...]

> > > To implement off-button you only need the APM_IOC_REJECT ioctl and
> > 
> > The problem on my computer with my (re)implementation of
> > APM_IOC_REJECT is that the screen goes into powersaving when the user
> > suspend is received, then turns it back on when APM_IOC_REJECT is sent
> > by apmd.
> 
> What is wrong with that ?

> Suspend is requested -> suspend is executed

> Suspend is canceled (rejected) -> suspend is canceled
> 
> Seems perfectly OK to me.

The sequence is in fact: suspend requested by BIOS -> suspend accepted
by kernel -> SUSPEND -> suspend rejected by apmd which is passed on by
kernel to BIOS -> REJECT=RESUME (if I understand correctly, this is
what seems to happen).

Sequence should be as in pmpolicy patch: suspend requested by BIOS ->
/sbin/powermanger decides to reject -> REJECT

[...]

> > Anyway it is fixed in my pmpolicy patch, and I don't need no
> > daemon so the code is a lot cleaner and simpler (no binary magic
> > number interfaces).
> 
> But there should be no policy in the kernel ! ;-)

Read the patch. Read the webpage:

        http://john.snoop.dk/programs/linux/offbutton

There is no policy in kernel.

-- 

	http://www.penguinpowered.com/~vii

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: kernel apm code
       [not found]         ` <"m24rwcjziu.fsf"@boreas.yi.org>
@ 2001-03-30 10:20           ` David Balazic
  0 siblings, 0 replies; 5+ messages in thread
From: David Balazic @ 2001-03-30 10:20 UTC (permalink / raw)
  To: John Fremlin
  Cc: linux-kernel@vger.kernel.org, linux-laptop, apm, apenwarr, sfr

John Fremlin wrote:
> 
>  David Balazic <david.balazic@uni-mb.si> writes:
> 
> > John Fremlin wrote:
> 
> [...]
> 
> > > > To implement off-button you only need the APM_IOC_REJECT ioctl and
> > >
> > > The problem on my computer with my (re)implementation of
> > > APM_IOC_REJECT is that the screen goes into powersaving when the user
> > > suspend is received, then turns it back on when APM_IOC_REJECT is sent
> > > by apmd.
> >
> > What is wrong with that ?
> 
> > Suspend is requested -> suspend is executed
> 
> > Suspend is canceled (rejected) -> suspend is canceled
> >
> > Seems perfectly OK to me.
> 
> The sequence is in fact: suspend requested by BIOS -> suspend accepted
> by kernel -> SUSPEND -> suspend rejected by apmd which is passed on by
> kernel to BIOS -> REJECT=RESUME (if I understand correctly, this is
> what seems to happen).
> 
> Sequence should be as in pmpolicy patch: suspend requested by BIOS ->
> /sbin/powermanger decides to reject -> REJECT

AFAICT , the kernel does not accept(*) any APM_EVENT until all userspace
"listeners" say it is OK. So until apmd doesn't reply, the kernel does
not accept the SUSPEND. If apmd says OK, kernel says OK to BIOS and SUSPEND
is activated, but if apmd says NO-NO, then the kernel rejects the SUSPEND
request and "nothing happens"

This is of course with a proper implementation of REJECT functionality
in the kernel apm driver. I don't know if it behaves like this in the
current IOC_AOM_REJECT version, but  it should :-)

* - by accept I mean : it receives a notification from BIOS and replies
OK to the BIOS. the BIOS doesn't change the powerstate until the kernel
responds with OK , IIRC

> 
> [...]
> 
> > > Anyway it is fixed in my pmpolicy patch, and I don't need no
> > > daemon so the code is a lot cleaner and simpler (no binary magic
> > > number interfaces).
> >
> > But there should be no policy in the kernel ! ;-)
> 
> Read the patch. Read the webpage:
> 
>         http://john.snoop.dk/programs/linux/offbutton
> 
> There is no policy in kernel.
> 
> --
> 
>         http://www.penguinpowered.com/~vii


-- 
David Balazic
--------------
"Be excellent to each other." - Bill & Ted
- - - - - - - - - - - - - - - - - - - - - -

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2001-03-30 10:21 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-03-27 14:40 kernel apm code David Balazic
2001-03-27 19:06 ` John Fremlin
     [not found] ` <"m28zlr58w9.fsf"@boreas.yi.org>
     [not found]   ` <3AC1C406.652D0207@uni-mb.si>
     [not found]     ` <"m2bsqmlyrh.fsf"@boreas.yi.org>
2001-03-29  9:25       ` David Balazic
2001-03-29 16:44         ` John Fremlin
     [not found]         ` <"m24rwcjziu.fsf"@boreas.yi.org>
2001-03-30 10:20           ` David Balazic

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox