Browse Source

Remove some old apm bits

Signed-off-by: Graham MacDonald <grahamamacdonald@gmail.com>
Graham MacDonald 5 years ago
parent
commit
a2d2a2ced5
3 changed files with 0 additions and 1334 deletions
  1. 0 60
      sys/man/3/apm
  2. 0 111
      sys/man/8/apm
  3. 0 1163
      sys/src/cmd/aux/apm.c

+ 0 - 60
sys/man/3/apm

@@ -1,60 +0,0 @@
-.TH APM 3
-.SH NAME
-apm \- Advanced Power Management 1.2 BIOS interface
-.SH SYNOPSIS
-.nf
-.B bind -a #P /dev
-
-.B /dev/apm
-.SH DESCRIPTION
-.PP
-This device presents a low-level interface to
-the APM 1.2 bios calls.
-It is enabled by adding the line
-.RB `` apm0= ''
-to 
-.IR plan9.ini .
-(The value after the equals sign is ignored; the presence of
-the line at all enables the driver.)
-It is only available on uniprocessor PCs.
-Writing a 386
-.B Ureg
-structure and then reading it back executes an APM call:
-the written registers are passed to the call,
-and the read registers are those returned by the call.
-.\" .PP
-.\" In addition, the following strings may be
-.\" written to
-.\" .B /dev/apm
-.\" to negotiate with other kernel devices about
-.\" suspension of the system.
-.\" .TP
-.\" .B "vote suspend
-.\" Poll kernel devices for objections to suspending the system.
-.\" The write succeeds only when no device objected.
-.\" .TP
-.\" .B "abort suspend
-.\" Notify kernel devices that the vote failed and the
-.\" suspension will not happen.
-.\" .TP
-.\" .B "commit suspend
-.\" Notify kernel devices that the vote succeeded and
-.\" suspension will happen.  The devices
-.\" may take measures such as disabling PCMCIA cards.
-.\" .TP
-.\" .B "resume suspend
-.\" Notify kernel devices that the system has come back
-.\" after a suspension.
-.\" The devices may take measures such as reenabling PCMCIA cards.
-.\" .PD
-.\" A similar set of messages governs entrance into
-.\" .B standby
-.\" mode.
-.PP
-This device is intended to enable more user-friendly
-interfaces such as 
-.IR apm (8).
-.SH SOURCE
-.B /sys/src/9/pc/apm.c
-.br
-.B /sys/src/9/pc/apmjump.s

+ 0 - 111
sys/man/8/apm

@@ -1,111 +0,0 @@
-.TH APM 8
-.SH NAME
-apm \- Advanced Power Management 1.2 BIOS interface
-.SH SYNOPSIS
-.I (in plan9.ini)
-.B apm0=
-.PP
-bind -a '#P' /dev
-.PP
-.B aux/apm
-[
-.B -d
-.I device
-]
-[
-.B -m
-.I mountpoint
-]
-[
-.B -s
-.I service
-]
-.SH DESCRIPTION
-.I Aux/apm
-presents at
-.I mountpoint
-(default
-.BR /mnt/apm )
-an interface to the APM 1.2 BIOS 
-(see
-.IR apm (3))
-.I device
-(the default is to try
-.BR /dev/apm ,
-followed by
-.BR #P/apm ).
-If a
-.I service
-is specified, the interface will be
-posted at
-.BI /srv/ service 
-as well.
-.PP
-The directory contains the following files.
-.TP
-.B battery
-Contains one line for each battery in the system.
-Each line lists three fields: the status (a string, one of
-.BR unknown ,
-.BR high ,
-.BR low ,
-.BR critical ,
-or
-.BR charging ),
-the percent charge remaining, and
-an estimate of the amount of time left in seconds.
-If either or both of the last two are unknown,
-the corresponding field will be zero.
-.TP
-.B ctl
-The
-.B ctl
-file is used to set power management modes for
-various parts of the system.
-Control messages are of the form
-.RI `` device " " verb ,''
-where 
-.I device
-is one of
-.BR system ,
-.BR display ,
-.BR storage ,
-.BR lpt ,
-.BR eia ,
-.BR network ,
-and
-.BR pcmcia ,
-and 
-.I verb is one of
-.BR enable ,
-.BR disable ,
-.BR standby ,
-and 
-.BR on .
-.B Enable
-and
-.B disable
-control whether power management is active
-for the device, while
-.B standby
-puts the device into standby mode
-and
-.B on
-brings it back to full power.
-.TP
-.B event
-Reads from this file will block until an APM event
-has occurred.
-A large enough read is guaranteed to return
-an integral number of textual event descriptions, one per line.
-.SH SOURCE
-.B /sys/src/cmd/aux/apm.c
-.br
-.B /acme/bin/Battery
-.SH BUGS
-The verbs
-.B suspend
-and
-.B off
-should be supported but doing so requires
-nontrivial help from the kernel.

+ 0 - 1163
sys/src/cmd/aux/apm.c

@@ -1,1163 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include <u.h>
-#include <libc.h>
-#include <ureg.h>
-typedef struct Ureg Ureg;
-#include <auth.h>
-#include <fcall.h>
-#include <thread.h>
-#include <9p.h>
-
-enum {
-	/* power mgmt event codes */
-	NotifyStandbyRequest		= 0x0001,
-	NotifySuspendRequest		= 0x0002,
-	NotifyNormalResume 		= 0x0003,
-	NotifyCriticalResume		= 0x0004,
-	NotifyBatteryLow			= 0x0005,
-	NotifyPowerStatusChange	= 0x0006,
-	NotifyUpdateTime			= 0x0007,
-	NotifyCriticalSuspend		= 0x0008,
-	NotifyUserStandbyRequest	= 0x0009,
-	NotifyUserSuspendRequest	= 0x000A,
-	NotifyStandbyResume		= 0x000B,
-	NotifyCapabilitiesChange		= 0x000C,
-
-	/* power device ids: add device number or All */
-	DevBios					= 0x0000,
-	DevAll					= 0x0001,
-	DevDisplay				= 0x0100,
-	DevStorage				= 0x0200,
-	DevLpt					= 0x0300,
-	DevEia					= 0x0400,
-	DevNetwork				= 0x0500,
-	DevPCMCIA				= 0x0600,
-	DevBattery				= 0x8000,
-		All					= 0x00FF,
-	DevMask					= 0xFF00,
-
-	/* power states */
-	PowerEnabled				= 0x0000,
-	PowerStandby				= 0x0001,
-	PowerSuspend				= 0x0002,
-	PowerOff					= 0x0003,
-
-	/* apm commands */
-	CmdInstallationCheck		= 0x5300,
-	CmdRealModeConnect		= 0x5301,
-	CmdProtMode16Connect		= 0x5302,
-	CmdProtMode32Connect		= 0x5303,
-	CmdDisconnect			= 0x5304,
-	CmdCpuIdle				= 0x5305,
-	CmdCpuBusy				= 0x5306,
-	CmdSetPowerState			= 0x5307,
-	CmdSetPowerMgmt	= 0x5308,
-	  DisablePowerMgmt	= 0x0000,		/* CX */
-	  EnablePowerMgmt	= 0x0001,
-	CmdRestoreDefaults			= 0x5309,
-	CmdGetPowerStatus			= 0x530A,
-	CmdGetPMEvent			= 0x530B,
-	CmdGetPowerState			= 0x530C,
-	CmdGetPowerMgmt			= 0x530D,
-	CmdDriverVersion			= 0x530E,
-
-	/* like CmdDisconnect but doesn't lose the interface */
-	CmdGagePowerMgmt	= 0x530F,
-	  DisengagePowerMgmt	= 0x0000,	/* CX */
-	  EngagePowerManagemenet	= 0x0001,
-
-	CmdGetCapabilities			= 0x5310,
-	  CapStandby				= 0x0001,
-	  CapSuspend				= 0x0002,
-	  CapTimerResumeStandby	= 0x0004,
-	  CapTimerResumeSuspend	= 0x0008,
-	  CapRingResumeStandby		= 0x0010,
-	  CapRingResumeSuspend	= 0x0020,
-	  CapPcmciaResumeStandby	= 0x0040,
-	  CapPcmciaResumeSuspend	= 0x0080,
-	  CapSlowCpu				= 0x0100,
-	CmdResumeTimer			= 0x5311,
-	  DisableResumeTimer		= 0x00,		/* CL */
-	  GetResumeTimer			= 0x01,
-	  SetResumeTimer			= 0x02,
-	CmdResumeOnRing			= 0x5312,
-	  DisableResumeOnRing		= 0x0000,		/* CX */
-	  EnableResumeOnRing		= 0x0001,
-	  GetResumeOnRing			= 0x0002,
-	CmdTimerRequests			= 0x5313,
-	  DisableTimerRequests		= 0x0000,		/* CX */
-	  EnableTimerRequests		= 0x0001,
-	  GetTimerRequests			= 0x0002,
-};
-
-static char* eventstr[] = {
-[NotifyStandbyRequest] =	"system standby request",
-[NotifySuspendRequest] =	"system suspend request",
-[NotifyNormalResume] =	"normal resume",
-[NotifyCriticalResume] =	"critical resume",
-[NotifyBatteryLow] =		"battery low",
-[NotifyPowerStatusChange] =	"power status change",
-[NotifyUpdateTime] =		"update time",
-[NotifyCriticalSuspend] =	"critical suspend",
-[NotifyUserStandbyRequest] =	"user standby request",
-[NotifyUserSuspendRequest] =	"user suspend request",
-[NotifyCapabilitiesChange] =	"capabilities change",
-};
-
-static char*
-apmevent(int e)
-{
-	static char buf[32];
-
-	if(0 <= e && e < nelem(eventstr) && eventstr[e])
-		return eventstr[e];
-
-	sprint(buf, "event 0x%x", (uint)e);
-	return buf;
-}
-
-static char *error[256] = {
-[0x01] =	"power mgmt disabled",
-[0x02] =	"real mode connection already established",
-[0x03] =	"interface not connected",
-[0x05] =	"16-bit protected mode connection already established",
-[0x06] =	"16-bit protected mode interface not supported",
-[0x07] =	"32-bit protected mode interface already established",
-[0x08] =	"32-bit protected mode interface not supported",
-[0x09] =	"unrecognized device id",
-[0x0A] =	"parameter value out of range",
-[0x0B] =	"interface not engaged",
-[0x0C] =	"function not supported",
-[0x0D] =	"resume timer disabled",
-[0x60] =	"unable to enter requested state",
-[0x80] =	"no power mgmt events pending",
-[0x86] =	"apm not present",
-};
-
-static char*
-apmerror(int id)
-{
-	char *e;
-	static char buf[64];
-
-	if(e = error[id&0xFF])
-		return e;
-
-	sprint(buf, "unknown error %x", id);
-	return buf;
-}
-
-QLock apmlock;
-int apmdebug;
-
-static int
-_apmcall(int fd, Ureg *u)
-{
-if(apmdebug) fprint(2, "call ax 0x%lx bx 0x%lx cx 0x%lx\n",
-	u->ax&0xFFFF, u->bx&0xFFFF, u->cx&0xFFFF);
-
-	seek(fd, 0, 0);
-	if(write(fd, u, sizeof *u) != sizeof *u)
-		return -1;
-
-	seek(fd, 0, 0);
-	if(read(fd, u, sizeof *u) != sizeof *u)
-		return -1;
-
-if(apmdebug) fprint(2, "flags 0x%lx ax 0x%lx bx 0x%lx cx 0x%lx\n",
-	u->flags&0xFFFF, u->ax&0xFFFF, u->bx&0xFFFF, u->cx&0xFFFF);
-
-	if(u->flags & 1) {	/* carry flag */
-		werrstr("%s", apmerror(u->ax>>8));
-		return -1;
-	}
-	return 0;
-}
-
-static int
-apmcall(int fd, Ureg *u)
-{
-	int r;
-
-	qlock(&apmlock);
-	r = _apmcall(fd, u);
-	qunlock(&apmlock);
-	return r;
-}
-
-typedef struct Apm Apm;
-typedef struct Battery Battery;
-
-struct Battery {
-	int status;
-	int percent;
-	int time;
-};
-
-enum {
-	Mbattery = 4,
-};
-struct Apm {
-	int fd;
-
-	int verhi;
-	int verlo;
-
-	int acstatus;
-	int nbattery;
-
-	int capabilities;
-
-	Battery battery[Mbattery];
-};
-enum {
-	AcUnknown = 0,		/* Apm.acstatus */
-	AcOffline,
-	AcOnline,
-	AcBackup,
-
-	BatteryUnknown = 0,	/* Battery.status */
-	BatteryHigh,
-	BatteryLow,
-	BatteryCritical,
-	BatteryCharging,
-};
-
-static char*
-acstatusstr[] = {
-[AcUnknown] =	"unknown",
-[AcOffline] =	"offline",
-[AcOnline] =	"online",
-[AcBackup] =	"backup",
-};
-
-static char*
-batterystatusstr[] = {
-[BatteryUnknown] = "unknown",
-[BatteryHigh] =	"high",
-[BatteryLow] =	"low",
-[BatteryCritical] =	"critical",
-[BatteryCharging] =	"charging",
-};
-
-static char*
-powerstatestr[] = {
-[PowerOff] =	"off",
-[PowerSuspend] =	"suspend",
-[PowerStandby] =	"standby",
-[PowerEnabled] =	"on",
-};
-
-static char*
-xstatus(char **str, int nstr, int x)
-{
-	if(0 <= x && x < nstr && str[x])
-		return str[x];
-	return "unknown";
-}
-
-static char*
-batterystatus(int b)
-{
-	return xstatus(batterystatusstr, nelem(batterystatusstr), b);
-}
-
-static char*
-powerstate(int s)
-{
-	return xstatus(powerstatestr, nelem(powerstatestr), s);
-}
-
-static char*
-acstatus(int a)
-{
-	return xstatus(acstatusstr, nelem(acstatusstr), a);
-}
-
-static int
-apmversion(Apm *apm)
-{
-	Ureg u;
-
-	u.ax = CmdDriverVersion;
-	u.bx = 0x0000;
-	u.cx = 0x0102;
-	if(apmcall(apm->fd, &u) < 0)
-		return -1;
-
-	apm->verhi = u.cx>>8;
-	apm->verlo = u.cx & 0xFF;
-
-	return u.cx;
-}
-
-static int
-apmcpuidle(Apm *apm)
-{
-	Ureg u;
-
-	u.ax = CmdCpuIdle;
-	return apmcall(apm->fd, &u);
-}
-
-static int
-apmcpubusy(Apm *apm)
-{
-	Ureg u;
-
-	u.ax = CmdCpuBusy;
-	return apmcall(apm->fd, &u);
-}
-
-static int
-apmsetpowerstate(Apm *apm, int dev, int state)
-{
-	Ureg u;
-
-	u.ax = CmdSetPowerState;
-	u.bx = dev;
-	u.cx = state;
-	return apmcall(apm->fd, &u);
-}
-
-static int
-apmsetpowermgmt(Apm *apm, int dev, int state)
-{
-	Ureg u;
-
-	u.ax = CmdSetPowerMgmt;
-	u.bx = dev;
-	u.cx = state;
-	return apmcall(apm->fd, &u);
-}
-
-static int
-apmrestoredefaults(Apm *apm, int dev)
-{
-	Ureg u;
-
-	u.ax = CmdRestoreDefaults;
-	u.bx = dev;
-	return apmcall(apm->fd, &u);
-}
-
-static int
-apmgetpowerstatus(Apm *apm, int dev)
-{
-	Battery *b;
-	Ureg u;
-
-	if(dev == DevAll)
-		b = &apm->battery[0];
-	else if((dev & DevMask) == DevBattery) {
-		if(dev - DevBattery < nelem(apm->battery))
-			b = &apm->battery[dev - DevBattery];
-		else
-			b = nil;
-	} else {
-		werrstr("bad device number");
-		return -1;
-	}
-
-	u.ax = CmdGetPowerStatus;
-	u.bx = dev;
-
-	if(apmcall(apm->fd, &u) < 0)
-		return -1;
-
-	if((dev & DevMask) == DevBattery)
-		apm->nbattery = u.si;
-
-	switch(u.bx>>8) {
-	case 0x00:
-		apm->acstatus = AcOffline;
-		break;
-	case 0x01:
-		apm->acstatus = AcOnline;
-		break;
-	case 0x02:
-		apm->acstatus = AcBackup;
-		break;
-	default:
-		apm->acstatus = AcUnknown;
-		break;
-	}
-
-	if(b != nil) {
-		switch(u.bx&0xFF) {
-		case 0x00:
-			b->status = BatteryHigh;
-			break;
-		case 0x01:
-			b->status = BatteryLow;
-			break;
-		case 0x02:
-			b->status = BatteryCritical;
-			break;
-		case 0x03:
-			b->status = BatteryCharging;
-			break;
-		default:
-			b->status = BatteryUnknown;
-			break;
-		}
-
-		if((u.cx & 0xFF) == 0xFF)
-			b->percent = -1;
-		else
-			b->percent = u.cx & 0xFF;
-
-		if((u.dx&0xFFFF) == 0xFFFF)
-			b->time = -1;
-		else if(u.dx & 0x8000)
-			b->time = 60*(u.dx & 0x7FFF);
-		else
-			b->time = u.dx & 0x7FFF;
-	}
-
-	return 0;
-}
-
-static int
-apmgetevent(Apm *apm)
-{
-	Ureg u;
-
-	u.ax = CmdGetPMEvent;
-	u.bx = 0;
-	u.cx = 0;
-
-	//when u.bx == NotifyNormalResume or NotifyCriticalResume,
-	//u.cx & 1 indicates PCMCIA socket was on while suspended,
-	//u.cx & 1 == 0 indicates was off.
-
-	if(apmcall(apm->fd, &u) < 0)
-		return -1;
-
-	return u.bx;
-}
-
-static int
-apmgetpowerstate(Apm *apm, int dev)
-{
-	Ureg u;
-
-	u.ax = CmdGetPowerState;
-	u.bx = dev;
-	u.cx = 0;
-
-	if(apmcall(apm->fd, &u) < 0)
-		return -1;
-
-	return u.cx;
-}
-
-static int
-apmgetpowermgmt(Apm *apm, int dev)
-{
-	Ureg u;
-
-	u.ax = CmdGetPowerMgmt;
-	u.bx = dev;
-
-	if(apmcall(apm->fd, &u) < 0)
-		return -1;
-
-	return u.cx;
-}
-
-static int
-apmgetcapabilities(Apm *apm)
-{
-	Ureg u;
-
-	u.ax = CmdGetCapabilities;
-	u.bx = DevBios;
-
-	if(apmcall(apm->fd, &u) < 0)
-		return -1;
-
-	apm->nbattery = u.bx & 0xFF;
-	apm->capabilities &= ~0xFFFF;
-	apm->capabilities |= u.cx;
-	return 0;
-}
-
-static int
-apminstallationcheck(Apm *apm)
-{
-	Ureg u;
-
-	u.ax = CmdInstallationCheck;
-	u.bx = DevBios;
-	if(apmcall(apm->fd, &u) < 0)
-		return -1;
-
-	if(u.cx & 0x0004)
-		apm->capabilities |= CapSlowCpu;
-	else
-		apm->capabilities &= ~CapSlowCpu;
-	return 0;
-}
-
-void
-apmsetdisplaystate(Apm *apm, int s)
-{
-	apmsetpowerstate(apm, DevDisplay, s);
-}
-
-void
-apmblank(Apm *apm)
-{
-	apmsetdisplaystate(apm, PowerStandby);
-}
-
-void
-apmunblank(Apm *apm)
-{
-	apmsetdisplaystate(apm, PowerEnabled);
-}
-
-void
-apmsuspend(Apm *apm)
-{
-	apmsetpowerstate(apm, DevAll, PowerSuspend);
-}
-
-Apm apm;
-
-void
-powerprint(void)
-{
-	print("%s", ctime(time(0)));
-	if(apmgetpowerstatus(&apm, DevAll) == 0) {
-		print("%d batteries\n", apm.nbattery);
-		print("battery 0: status %s percent %d time %d:%.2d\n",
-			batterystatus(apm.battery[0].status), apm.battery[0].percent,
-			apm.battery[0].time/60, apm.battery[0].time%60);
-	}
-}
-
-void*
-erealloc(void *v, uint32_t n)
-{
-	v = realloc(v, n);
-	if(v == nil)
-		sysfatal("out of memory reallocating %lu", n);
-	setmalloctag(v, getcallerpc());
-	return v;
-}
-
-void*
-emalloc(uint32_t n)
-{
-	void *v;
-
-	v = malloc(n);
-	if(v == nil)
-		sysfatal("out of memory allocating %lu", n);
-	memset(v, 0, n);
-	setmalloctag(v, getcallerpc());
-	return v;
-}
-
-char*
-estrdup(char *s)
-{
-	int l;
-	char *t;
-
-	if (s == nil)
-		return nil;
-	l = strlen(s)+1;
-	t = emalloc(l);
-	memcpy(t, s, l);
-	setmalloctag(t, getcallerpc());
-	return t;
-}
-
-char*
-estrdupn(char *s, int n)
-{
-	int l;
-	char *t;
-
-	l = strlen(s);
-	if(l > n)
-		l = n;
-	t = emalloc(l+1);
-	memmove(t, s, l);
-	t[l] = '\0';
-	setmalloctag(t, getcallerpc());
-	return t;
-}
-
-enum {
-	Qroot = 0,
-	Qevent,
-	Qbattery,
-	Qctl,
-};
-
-static void rootread(Req*);
-static void eventread(Req*);
-static void ctlread(Req*);
-static void ctlwrite(Req*);
-static void batteryread(Req*);
-
-typedef struct Dfile Dfile;
-struct Dfile {
-	Qid qid;
-	char *name;
-	uint32_t mode;
-	void (*read)(Req*);
-	void (*write)(Req*);
-};
-
-Dfile dfile[] = {
-	{ {Qroot,0,QTDIR},		"/",		DMDIR|0555,	rootread,		nil, },
-	{ {Qevent},		"event",	0444,		eventread,	nil, },
-	{ {Qbattery},	"battery",	0444,		batteryread,	nil, },
-	{ {Qctl},		"ctl",		0666,		ctlread,		ctlwrite, },
-};
-
-static int
-fillstat(uint64_t path, Dir *d, int doalloc)
-{
-	int i;
-
-	for(i=0; i<nelem(dfile); i++)
-		if(path==dfile[i].qid.path)
-			break;
-	if(i==nelem(dfile))
-		return -1;
-
-	memset(d, 0, sizeof *d);
-	d->uid = doalloc ? estrdup("apm") : "apm";
-	d->gid = doalloc ? estrdup("apm") : "apm";
-	d->length = 0;
-	d->name = doalloc ? estrdup(dfile[i].name) : dfile[i].name;
-	d->mode = dfile[i].mode;
-	d->atime = d->mtime = time(0);
-	d->qid = dfile[i].qid;
-	return 0;
-}
-
-static char*
-fswalk1(Fid *fid, char *name, Qid *qid)
-{
-	int i;
-
-	if(strcmp(name, "..")==0){
-		*qid = dfile[0].qid;
-		fid->qid = *qid;
-		return nil;
-	}
-
-	for(i=1; i<nelem(dfile); i++){	/* i=1: 0 is root dir */
-		if(strcmp(dfile[i].name, name)==0){
-			*qid = dfile[i].qid;
-			fid->qid = *qid;
-			return nil;
-		}
-	}
-	return "file does not exist";
-}
-
-static void
-fsopen(Req *r)
-{
-	switch((uint32_t)r->fid->qid.path){
-	case Qroot:
-		r->fid->aux = (void*)0;
-		respond(r, nil);
-		return;
-
-	case Qevent:
-	case Qbattery:
-		if(r->ifcall.mode == OREAD){
-			respond(r, nil);
-			return;
-		}
-		break;
-
-	case Qctl:
-		if((r->ifcall.mode&~(OTRUNC|OREAD|OWRITE|ORDWR)) == 0){
-			respond(r, nil);
-			return;
-		}
-		break;
-	}
-	respond(r, "permission denied");
-	return;
-}
-
-static void
-fsstat(Req *r)
-{
-	fillstat(r->fid->qid.path, &r->d, 1);
-	respond(r, nil);
-}
-
-static void
-fsread(Req *r)
-{
-	dfile[r->fid->qid.path].read(r);
-}
-
-static void
-fswrite(Req *r)
-{
-	dfile[r->fid->qid.path].write(r);
-}
-
-static void
-rootread(Req *r)
-{
-	int n;
-	uint64_t offset;
-	char *p, *ep;
-	Dir d;
-
-	if(r->ifcall.offset == 0)
-		offset = 0;
-	else
-		offset = (uint64_t)r->fid->aux;
-
-	p = r->ofcall.data;
-	ep = r->ofcall.data+r->ifcall.count;
-
-	if(offset == 0)		/* skip root */
-		offset = 1;
-	for(; p+2 < ep; p+=n){
-		if(fillstat(offset, &d, 0) < 0)
-			break;
-		n = convD2M(&d, (uint8_t*)p, ep-p);
-		if(n <= BIT16SZ)
-			break;
-		offset++;
-	}
-	r->fid->aux = (void*)offset;
-	r->ofcall.count = p - r->ofcall.data;
-	respond(r, nil);
-}
-
-static void
-batteryread(Req *r)
-{
-	char buf[Mbattery*80], *ep, *p;
-	int i;
-
-	apmgetpowerstatus(&apm, DevAll);
-
-	p = buf;
-	ep = buf+sizeof buf;
-	*p = '\0';	/* could be no batteries */
-	for(i=0; i<apm.nbattery && i<Mbattery; i++)
-		p += snprint(p, ep-p, "%s %d %d\n",
-			batterystatus(apm.battery[i].status),
-			apm.battery[i].percent, apm.battery[i].time);
-
-	readstr(r, buf);
-	respond(r, nil);
-}
-
-int
-iscmd(char *p, char *cmd)
-{
-	int l;
-
-	l = strlen(cmd);
-	return strncmp(p, cmd, l)==0 && p[l]=='\0' || p[l]==' ' || p[l]=='\t';
-}
-
-char*
-skip(char *p, char *cmd)
-{
-	p += strlen(cmd);
-	while(*p==' ' || *p=='\t')
-		p++;
-	return p;
-}
-
-static void
-respondx(Req *r, int c)
-{
-	char err[ERRMAX];
-
-	if(c == 0)
-		respond(r, nil);
-	else{
-		rerrstr(err, sizeof err);
-		respond(r, err);
-	}
-}
-
-/*
- * we don't do suspend because it messes up the
- * cycle counter as well as the pcmcia ethernet cards.
- */
-static void
-ctlwrite(Req *r)
-{
-	char buf[80], *p, *q;
-	int dev;
-	int32_t count;
-
-	count = r->ifcall.count;
-	if(count > sizeof(buf)-1)
-		count = sizeof(buf)-1;
-	memmove(buf, r->ifcall.data, count);
-	buf[count] = '\0';
-
-	if(count && buf[count-1] == '\n'){
-		--count;
-		buf[count] = '\0';
-	}
-
-	q = buf;
-	p = strchr(q, ' ');
-	if(p==nil)
-		p = q+strlen(q);
-	else
-		*p++ = '\0';
-
-	if(strcmp(q, "")==0 || strcmp(q, "system")==0)
-		dev = DevAll;
-	else if(strcmp(q, "display")==0)
-		dev = DevDisplay;
-	else if(strcmp(q, "storage")==0)
-		dev = DevStorage;
-	else if(strcmp(q, "lpt")==0)
-		dev = DevLpt;
-	else if(strcmp(q, "eia")==0)
-		dev = DevEia;
-	else if(strcmp(q, "network")==0)
-		dev = DevNetwork;
-	else if(strcmp(q, "pcmcia")==0)
-		dev = DevPCMCIA;
-	else{
-		respond(r, "unknown device");
-		return;
-	}
-
-	if(strcmp(p, "enable")==0)
-		respondx(r, apmsetpowermgmt(&apm, dev, EnablePowerMgmt));
-	else if(strcmp(p, "disable")==0)
-		respondx(r, apmsetpowermgmt(&apm, dev, DisablePowerMgmt));
-	else if(strcmp(p, "standby")==0)
-		respondx(r, apmsetpowerstate(&apm, dev, PowerStandby));
-	else if(strcmp(p, "on")==0)
-		respondx(r, apmsetpowerstate(&apm, dev, PowerEnabled));
-/*
-	else if(strcmp(p, "off")==0)
-		respondx(r, apmsetpowerstate(&apm, dev, PowerOff));
-*/
-	else if(strcmp(p, "suspend")==0)
-		respondx(r, apmsetpowerstate(&apm, dev, PowerSuspend));
-	else
-		respond(r, "unknown verb");
-}
-
-static int
-statusline(char *buf, int nbuf, char *name, int dev)
-{
-	int s;
-	char *state;
-
-	state = "unknown";
-	if((s = apmgetpowerstate(&apm, dev)) >= 0)
-		state = powerstate(s);
-	return snprint(buf, nbuf, "%s %s\n", name, state);
-}
-
-static void
-ctlread(Req *r)
-{
-	char buf[256+7*50], *ep, *p;
-
-	p = buf;
-	ep = buf+sizeof buf;
-
-	p += snprint(p, ep-p, "ac %s\n", acstatus(apm.acstatus));
-	p += snprint(p, ep-p, "capabilities");
-	if(apm.capabilities & CapStandby)
-		p += snprint(p, ep-p, " standby");
-	if(apm.capabilities & CapSuspend)
-		p += snprint(p, ep-p, " suspend");
-	if(apm.capabilities & CapSlowCpu)
-		p += snprint(p, ep-p, " slowcpu");
-	p += snprint(p, ep-p, "\n");
-
-	p += statusline(p, ep-p, "system", DevAll);
-	p += statusline(p, ep-p, "display", DevDisplay);
-	p += statusline(p, ep-p, "storage", DevStorage);
-	p += statusline(p, ep-p, "lpt", DevLpt);
-	p += statusline(p, ep-p, "eia", DevEia|All);
-	p += statusline(p, ep-p, "network", DevNetwork|All);
-	p += statusline(p, ep-p, "pcmcia", DevPCMCIA|All);
-	USED(p);
-
-	readstr(r, buf);
-	respond(r, nil);
-}
-
-enum {
-	STACK = 16384,
-};
-
-Channel *creq;
-Channel *cflush;
-Channel *cevent;
-Req *rlist, **tailp;
-int rp, wp;
-int nopoll;
-char eventq[32][80];
-
-static void
-flushthread(void *v)
-{
-	Req *r, *or, **rq;
-
-	threadsetname("flushthread");
-	while(r = recvp(cflush)){
-		or = r->oldreq;
-		for(rq=&rlist; *rq; rq=&(*rq)->aux){
-			if(*rq == or){
-				*rq = or->aux;
-				if(tailp==&or->aux)
-					tailp = rq;
-				respond(or, "interrupted");
-				break;
-			}
-		}
-		respond(r, nil);
-	}
-}
-
-static void
-answerany(void)
-{
-	char *buf;
-	int l, m;
-	Req *r;
-
-	if(rlist==nil || rp==wp)
-		return;
-
-	while(rlist && rp != wp){
-		r = rlist;
-		rlist = r->aux;
-		if(rlist==nil)
-			tailp = &rlist;
-
-		l = 0;
-		buf = r->ofcall.data;
-		m = r->ifcall.count;
-		while(rp != wp){
-			if(l+strlen(eventq[rp]) <= m){
-				strcpy(buf+l, eventq[rp]);
-				l += strlen(buf+l);
-			}else if(l==0){
-				strncpy(buf, eventq[rp], m-1);
-				buf[m-1] = '\0';
-				l += m;
-			}else
-				break;
-			rp++;
-			if(rp == nelem(eventq))
-				rp = 0;
-		}
-		r->ofcall.count = l;
-		respond(r, nil);
-	}
-}
-
-static void
-eventwatch(void *v)
-{
-	int e, s;
-
-	threadsetname("eventwatch");
-	for(;;){
-		s = 0;
-		while((e = apmgetevent(&apm)) >= 0){
-			sendul(cevent, e);
-			s = 1;
-		}
-		if(s)
-			sendul(cevent, -1);
-		if (sleep(750) < 0)
-			break;
-	}
-}
-
-static void
-eventthread(void *v)
-{
-	int e;
-
-	threadsetname("eventthread");
-	for(;;){
-		while((e = recvul(cevent)) >= 0){
-			snprint(eventq[wp], sizeof(eventq[wp])-1, "%s", apmevent(e));
-			strcat(eventq[wp], "\n");
-			wp++;
-			if(wp==nelem(eventq))
-				wp = 0;
-			if(wp+1==rp || (wp+1==nelem(eventq) && rp==0))
-				break;
-		}
-		answerany();
-	}
-}
-
-static void
-eventproc(void *v)
-{
-	Req *r;
-
-	threadsetname("eventproc");
-
-	creq = chancreate(sizeof(Req*), 0);
-	cevent = chancreate(sizeof(uint32_t), 0);
-	cflush = chancreate(sizeof(Req*), 0);
-
-	tailp = &rlist;
-	if(!nopoll)
-		proccreate(eventwatch, nil, STACK);
-	threadcreate(eventthread, nil, STACK);
-	threadcreate(flushthread, nil, STACK);
-
-	while(r = recvp(creq)){
-		*tailp = r;
-		r->aux = nil;
-		tailp = &r->aux;
-		answerany();
-	}
-}
-
-static void
-fsflush(Req *r)
-{
-	sendp(cflush, r);
-}
-
-static void
-eventread(Req *r)
-{
-	sendp(creq, r);
-}
-
-static void
-fsattach(Req *r)
-{
-	char *spec;
-	static int first = 1;
-
-	spec = r->ifcall.aname;
-
-	if(first){
-		first = 0;
-		proccreate(eventproc, nil, STACK);
-	}
-
-	if(spec && spec[0]){
-		respond(r, "invalid attach specifier");
-		return;
-	}
-	r->fid->qid = dfile[0].qid;
-	r->ofcall.qid = dfile[0].qid;
-	respond(r, nil);
-}
-
-Srv fs = {
-.attach=	fsattach,
-.walk1=	fswalk1,
-.open=	fsopen,
-.read=	fsread,
-.write=	fswrite,
-.stat=	fsstat,
-.flush=	fsflush,
-};
-
-void
-usage(void)
-{
-	fprint(2, "usage: aux/apm [-ADPi] [-d /dev/apm] [-m /mnt/apm] [-s service]\n");
-	exits("usage");
-}
-
-void
-threadmain(int argc, char **argv)
-{
-	char *dev, *mtpt, *srv;
-
-	dev = nil;
-	mtpt = "/mnt/apm";
-	srv = nil;
-	ARGBEGIN{
-	case 'A':
-		apmdebug = 1;
-		break;
-	case 'D':
-		chatty9p = 1;
-		break;
-	case 'P':
-		nopoll = 1;
-		break;
-	case 'd':
-		dev = EARGF(usage());
-		break;
-	case 'i':
-		fs.nopipe++;
-		fs.infd = 0;
-		fs.outfd = 1;
-		mtpt = nil;
-		break;
-	case 'm':
-		mtpt = EARGF(usage());
-		break;
-	case 's':
-		srv = EARGF(usage());
-		break;
-	}ARGEND
-
-	if(dev == nil){
-		if((apm.fd = open("/dev/apm", ORDWR)) < 0
-		&& (apm.fd = open("#P/apm", ORDWR)) < 0){
-			fprint(2, "open %s: %r\n", dev);
-			threadexitsall("open");
-		}
-	} else if((apm.fd = open(dev, ORDWR)) < 0){
-		fprint(2, "open %s: %r\n", dev);
-		threadexitsall("open");
-	}
-
-	if(apmversion(&apm) < 0){
-		fprint(2, "cannot get apm version: %r\n");
-		threadexitsall("apmversion");
-	}
-
-	if(apm.verhi < 1 || (apm.verhi==1 && apm.verlo < 2)){
-		fprint(2, "apm version %d.%d not supported\n", apm.verhi, apm.verlo);
-		threadexitsall("apmversion");
-	}
-
-	if(apmgetcapabilities(&apm) < 0)
-		fprint(2, "warning: cannot read apm capabilities: %r\n");
-
-	apminstallationcheck(&apm);
-	apmcpuidle(&apm);
-
-	rfork(RFNOTEG);
-	threadpostmountsrv(&fs, srv, mtpt, MREPL);
-}