summaryrefslogtreecommitdiff
path: root/sys/arch/sparc
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2005-03-29 16:26:46 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2005-03-29 16:26:46 +0000
commitf4ddf48fe34dc16fd30f0f844f03d285d0f3386d (patch)
tree86f0d8b496021105346b74c0c20cab54254773d8 /sys/arch/sparc
parenteef7068a6de10b8f1c78351ad85efa001012c7a2 (diff)
Add an apm interface to the tctrl(4) device found on SPARCbooks; currently
limited to power change events and battery status retrieval. ok deraadt@ mickey@
Diffstat (limited to 'sys/arch/sparc')
-rw-r--r--sys/arch/sparc/dev/tctrl.c340
-rw-r--r--sys/arch/sparc/dev/ts102reg.h3
-rw-r--r--sys/arch/sparc/include/apmvar.h124
-rw-r--r--sys/arch/sparc/include/conf.h10
-rw-r--r--sys/arch/sparc/sparc/conf.c6
5 files changed, 472 insertions, 11 deletions
diff --git a/sys/arch/sparc/dev/tctrl.c b/sys/arch/sparc/dev/tctrl.c
index 6409aaca8c7..3f76cf2660c 100644
--- a/sys/arch/sparc/dev/tctrl.c
+++ b/sys/arch/sparc/dev/tctrl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tctrl.c,v 1.9 2005/03/29 12:55:55 miod Exp $ */
+/* $OpenBSD: tctrl.c,v 1.10 2005/03/29 16:26:44 miod Exp $ */
/* $NetBSD: tctrl.c,v 1.2 1999/08/11 00:46:06 matt Exp $ */
/*-
@@ -36,20 +36,75 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * The /dev/apm{,ctl} interface code falls under the following license
+ * terms:
+ *
+ * Copyright (c) 1998-2001 Michael Shalayeff. All rights reserved.
+ * Copyright (c) 1995 John T. Kohl. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/device.h>
+#include <sys/event.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/proc.h>
#include <sys/timeout.h>
+#include <machine/apmvar.h>
#include <machine/autoconf.h>
+#include <machine/conf.h>
#include <machine/cpu.h>
#include <sparc/dev/ts102reg.h>
#include <sparc/dev/tctrlvar.h>
+/*
+ * Flags to control kernel display
+ * SCFLAG_NOPRINT: do not output APM power messages due to
+ * a power change event.
+ *
+ * SCFLAG_PCTPRINT: do not output APM power messages due to
+ * to a power change event unless the battery
+ * percentage changes.
+ */
+
+#define SCFLAG_NOPRINT 0x0008000
+#define SCFLAG_PCTPRINT 0x0004000
+#define SCFLAG_PRINT (SCFLAG_NOPRINT|SCFLAG_PCTPRINT)
+
const char *tctrl_ext_statuses[16] = {
"main power available",
"internal battery attached",
@@ -96,6 +151,10 @@ struct tctrl_softc {
u_int sc_bellvol;
struct timeout sc_tmo;
+
+ /* /dev/apm{,ctl} fields */
+ struct klist sc_note;
+ u_int sc_apmflags;
};
int tctrl_match(struct device *, void *, void *);
@@ -113,6 +172,8 @@ void tctrl_request(struct tctrl_softc *, struct tctrl_req *);
void tctrl_tft(struct tctrl_softc *);
void tctrl_write_data(struct tctrl_softc *, u_int8_t);
+int apm_record_event(struct tctrl_softc *, u_int);
+
struct cfattach tctrl_ca = {
sizeof(struct tctrl_softc), tctrl_match, tctrl_attach
};
@@ -425,17 +486,23 @@ tctrl_read_event_status(void *arg)
#ifdef TCTRLDEBUG
/* Obviously status change */
if (v & TS102_EVENT_STATUS_VERY_LOW_POWER_WARNING) {
- printf("%s: Battery level change\n", sc->sc_dev.dv_xname);
+ if (sc->sc_apmflags & SCFLAG_PCTPRINT)
+ printf("%s: Battery level change\n",
+ sc->sc_dev.dv_xname);
}
#endif
if (v & TS102_EVENT_STATUS_LOW_POWER_WARNING) {
- printf("%s: LOW POWER WARNING!\n", sc->sc_dev.dv_xname);
+ if ((sc->sc_apmflags & SCFLAG_NOPRINT) == 0)
+ printf("%s: LOW POWER WARNING!\n", sc->sc_dev.dv_xname);
+ apm_record_event(sc, APM_BATTERY_LOW);
}
if (v & TS102_EVENT_STATUS_DC_STATUS_CHANGE) {
tctrl_read_ext_status(sc);
- printf("%s: main power %s\n", sc->sc_dev.dv_xname,
- (sc->sc_ext_status & TS102_EXT_STATUS_MAIN_POWER_AVAILABLE) ?
- "restored" : "removed");
+ if ((sc->sc_apmflags & SCFLAG_NOPRINT) == 0)
+ printf("%s: main power %s\n", sc->sc_dev.dv_xname,
+ (sc->sc_ext_status & TS102_EXT_STATUS_MAIN_POWER_AVAILABLE) ?
+ "restored" : "removed");
+ apm_record_event(sc, APM_POWER_CHANGE);
#if 0 /* automatically done for us */
tctrl_lcd(sc, ~TS102_LCD_DC_OK,
sc->sc_ext_status & TS102_EXT_STATUS_MAIN_POWER_AVAILABLE ?
@@ -788,3 +855,264 @@ tadpole_bell(u_int duration, u_int freq, u_int volume)
return (1);
}
+
+/*
+ * /dev/apm{,ctl} interface code
+ */
+
+#define APMUNIT(dev) (minor(dev)&0xf0)
+#define APMDEV(dev) (minor(dev)&0x0f)
+#define APMDEV_NORMAL 0
+#define APMDEV_CTL 8
+
+int apmkqfilter(dev_t dev, struct knote *kn);
+void filt_apmrdetach(struct knote *kn);
+int filt_apmread(struct knote *kn, long hint);
+
+struct filterops apmread_filtops =
+ { 1, NULL, filt_apmrdetach, filt_apmread};
+
+#define SCFLAG_OREAD (1 << 0)
+#define SCFLAG_OWRITE (1 << 1)
+#define SCFLAG_OPEN (SCFLAG_OREAD|SCFLAG_OWRITE)
+
+int
+apmopen(dev_t dev, int flag, int mode, struct proc *p)
+{
+ struct tctrl_softc *sc;
+ int error = 0;
+
+ if (tctrl_cd.cd_devs == NULL
+ || tctrl_cd.cd_ndevs == 0
+ || tctrl_cd.cd_devs[0] == NULL) {
+ return (ENXIO);
+ }
+
+ /* apm0 only */
+ if (APMUNIT(dev) != 0)
+ return (ENODEV);
+
+ sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0];
+
+ switch (APMDEV(dev)) {
+ case APMDEV_CTL:
+ if (!(flag & FWRITE)) {
+ error = EINVAL;
+ break;
+ }
+ if (sc->sc_apmflags & SCFLAG_OWRITE) {
+ error = EBUSY;
+ break;
+ }
+ sc->sc_apmflags |= SCFLAG_OWRITE;
+ break;
+ case APMDEV_NORMAL:
+ if (!(flag & FREAD) || (flag & FWRITE)) {
+ error = EINVAL;
+ break;
+ }
+ sc->sc_apmflags |= SCFLAG_OREAD;
+ break;
+ default:
+ error = ENXIO;
+ break;
+ }
+ return (error);
+}
+
+int
+apmclose(dev_t dev, int flag, int mode, struct proc *p)
+{
+ struct tctrl_softc *sc;
+
+ if (tctrl_cd.cd_devs == NULL
+ || tctrl_cd.cd_ndevs == 0
+ || tctrl_cd.cd_devs[0] == NULL) {
+ return (ENXIO);
+ }
+
+ /* apm0 only */
+ if (APMUNIT(dev) != 0)
+ return (ENODEV);
+
+ sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0];
+
+ switch (APMDEV(dev)) {
+ case APMDEV_CTL:
+ sc->sc_apmflags &= ~SCFLAG_OWRITE;
+ break;
+ case APMDEV_NORMAL:
+ sc->sc_apmflags &= ~SCFLAG_OREAD;
+ break;
+ }
+ return (0);
+}
+
+int
+apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ struct tctrl_softc *sc;
+ struct tctrl_req req;
+ struct apm_power_info *power;
+ u_int8_t c;
+ int error = 0;
+
+ if (tctrl_cd.cd_devs == NULL
+ || tctrl_cd.cd_ndevs == 0
+ || tctrl_cd.cd_devs[0] == NULL) {
+ return (ENXIO);
+ }
+
+ /* apm0 only */
+ if (APMUNIT(dev) != 0)
+ return (ENODEV);
+
+ sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0];
+
+ switch (cmd) {
+ /* some ioctl names from linux */
+ case APM_IOC_STANDBY:
+ if ((flag & FWRITE) == 0)
+ error = EBADF;
+ else
+ error = EOPNOTSUPP; /* XXX */
+ break;
+ case APM_IOC_SUSPEND:
+ if ((flag & FWRITE) == 0)
+ error = EBADF;
+ else
+ error = EOPNOTSUPP; /* XXX */
+ break;
+ case APM_IOC_PRN_CTL:
+ if ((flag & FWRITE) == 0)
+ error = EBADF;
+ else {
+ int flag = *(int *)data;
+ switch (flag) {
+ case APM_PRINT_ON: /* enable printing */
+ sc->sc_apmflags &= ~SCFLAG_PRINT;
+ break;
+ case APM_PRINT_OFF: /* disable printing */
+ sc->sc_apmflags &= ~SCFLAG_PRINT;
+ sc->sc_apmflags |= SCFLAG_NOPRINT;
+ break;
+ case APM_PRINT_PCT: /* disable some printing */
+ sc->sc_apmflags &= ~SCFLAG_PRINT;
+ sc->sc_apmflags |= SCFLAG_PCTPRINT;
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ }
+ break;
+ case APM_IOC_GETPOWER:
+ power = (struct apm_power_info *)data;
+
+ req.cmdbuf[0] = TS102_OP_RD_INT_CHARGE_RATE;
+ req.cmdlen = 1;
+ req.rsplen = 2;
+ tctrl_request(sc, &req);
+ if (req.rspbuf[0] != 0)
+ power->battery_state = APM_BATT_CHARGING;
+ else
+ power->battery_state = APM_BATT_UNKNOWN;
+
+ req.cmdbuf[0] = TS102_OP_RD_INT_CHARGE_LEVEL;
+ req.cmdlen = 1;
+ req.rsplen = 3;
+ tctrl_request(sc, &req);
+
+ c = req.rspbuf[0];
+ if (c == TS102_CHARGE_UNKNOWN)
+ c = 0;
+ power->battery_life = c;
+ power->minutes_left = (u_int)-1; /* unknown */
+ if (power->battery_state != APM_BATT_CHARGING) {
+ if (c < 0x20)
+ power->battery_state = APM_BATT_CRITICAL;
+ else if (c < 0x40)
+ power->battery_state = APM_BATT_HIGH;
+ else if (c < 0x66)
+ power->battery_state = APM_BATT_HIGH;
+ }
+
+#if 0
+ tctrl_read_ext_status(sc);
+#endif
+ if (sc->sc_ext_status & TS102_EXT_STATUS_MAIN_POWER_AVAILABLE)
+ power->ac_state = APM_AC_ON;
+ else
+ power->ac_state = APM_AC_OFF;
+ break;
+
+ default:
+ error = ENOTTY;
+ }
+
+ return (error);
+}
+
+int
+apm_record_event(struct tctrl_softc *sc, u_int type)
+{
+ static int apm_evindex;
+
+ /* skip if no user waiting */
+ if ((sc->sc_apmflags & SCFLAG_OPEN) == 0)
+ return (1);
+
+ apm_evindex++;
+ KNOTE(&sc->sc_note, APM_EVENT_COMPOSE(type, apm_evindex));
+
+ return (0);
+}
+
+void
+filt_apmrdetach(struct knote *kn)
+{
+ struct tctrl_softc *sc = (struct tctrl_softc *)kn->kn_hook;
+
+ SLIST_REMOVE(&sc->sc_note, kn, knote, kn_selnext);
+}
+
+int
+filt_apmread(struct knote *kn, long hint)
+{
+ /* XXX weird kqueue_scan() semantics */
+ if (hint && !kn->kn_data)
+ kn->kn_data = (int)hint;
+
+ return (1);
+}
+
+int
+apmkqfilter(dev_t dev, struct knote *kn)
+{
+ struct tctrl_softc *sc;
+
+ if (tctrl_cd.cd_devs == NULL
+ || tctrl_cd.cd_ndevs == 0
+ || tctrl_cd.cd_devs[0] == NULL) {
+ return (ENXIO);
+ }
+
+ /* apm0 only */
+ if (APMUNIT(dev) != 0)
+ return (ENODEV);
+
+ sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0];
+
+ switch (kn->kn_filter) {
+ case EVFILT_READ:
+ kn->kn_fop = &apmread_filtops;
+ break;
+ default:
+ return (1);
+ }
+
+ kn->kn_hook = (caddr_t)sc;
+ SLIST_INSERT_HEAD(&sc->sc_note, kn, kn_selnext);
+
+ return (0);
+}
diff --git a/sys/arch/sparc/dev/ts102reg.h b/sys/arch/sparc/dev/ts102reg.h
index e03b6954214..e42a2ecf4e0 100644
--- a/sys/arch/sparc/dev/ts102reg.h
+++ b/sys/arch/sparc/dev/ts102reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ts102reg.h,v 1.3 2003/06/18 17:50:23 miod Exp $ */
+/* $OpenBSD: ts102reg.h,v 1.4 2005/03/29 16:26:44 miod Exp $ */
/* $NetBSD: ts102reg.h,v 1.7 2002/09/29 23:23:58 wiz Exp $ */
/*-
@@ -348,6 +348,7 @@ enum ts102_opcode { /* Argument Returned */
TS102_OP_ADMIN_VRFY_SYSTEM_PASS=0x73, /* len <pass> ack + status */
TS102_OP_RD_INT_CHARGE_LEVEL=0x7a, /* ack + 2 byte */
TS102_OP_RD_EXT_CHARGE_LEVEL=0x7b, /* ack + 2 byte */
+#define TS102_CHARGE_UNKNOWN 0xfa
TS102_OP_SLEEP=0x80, /* supposedly sleeps, not sure */
TS102_OP_ADMIN_POWER_OFF=0x82, /* len <pass> none */
TS102_OP_ADMIN_POWER_RESTART=0x83, /* msb,xx,lsb none */
diff --git a/sys/arch/sparc/include/apmvar.h b/sys/arch/sparc/include/apmvar.h
new file mode 100644
index 00000000000..44404357b8f
--- /dev/null
+++ b/sys/arch/sparc/include/apmvar.h
@@ -0,0 +1,124 @@
+/* $OpenBSD: apmvar.h,v 1.1 2005/03/29 16:26:44 miod Exp $ */
+
+/*
+ * Copyright (c) 1995 John T. Kohl
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef _MACHINE_APMVAR_H_
+#define _MACHINE_APMVAR_H_
+
+#include <sys/ioccom.h>
+
+/*
+ * This is a subset of the Advanced Power Management (v1.0 and v1.1
+ * specification) functions/defines/etc, covering the abilities of
+ * the tctrl driver.
+ */
+
+#define APM_POWER_STATUS 0x530a
+#define APM_AC_OFF 0x00
+#define APM_AC_ON 0x01
+#define APM_AC_BACKUP 0x02
+#define APM_AC_UNKNOWN 0xff
+#define APM_BATT_HIGH 0x00
+#define APM_BATT_LOW 0x01
+#define APM_BATT_CRITICAL 0x02
+#define APM_BATT_CHARGING 0x03
+#define APM_BATT_UNKNOWN 0xff
+#define APM_BATT_FLAG_HIGH 0x01
+#define APM_BATT_FLAG_LOW 0x02
+#define APM_BATT_FLAG_CRITICAL 0x04
+#define APM_BATT_FLAG_CHARGING 0x08
+#define APM_BATT_FLAG_NOBATTERY 0x10
+#define APM_BATT_FLAG_NOSYSBATT 0x80
+#define APM_BATT_LIFE_UNKNOWN 0xff
+
+#define APM_GET_PM_EVENT 0x530b
+#define APM_NOEVENT 0x0000
+#define APM_STANDBY_REQ 0x0001 /* %bx on return */
+#define APM_SUSPEND_REQ 0x0002
+#define APM_NORMAL_RESUME 0x0003
+#define APM_CRIT_RESUME 0x0004 /* suspend/resume happened
+ without us */
+#define APM_BATTERY_LOW 0x0005
+#define APM_POWER_CHANGE 0x0006
+#define APM_UPDATE_TIME 0x0007
+#define APM_CRIT_SUSPEND_REQ 0x0008
+#define APM_USER_STANDBY_REQ 0x0009
+#define APM_USER_SUSPEND_REQ 0x000A
+#define APM_SYS_STANDBY_RESUME 0x000B
+#define APM_CAPABILITY_CHANGE 0x000C /* apm v1.2 */
+
+#define APM_EVENT_MASK 0xffff
+
+#define APM_EVENT_COMPOSE(t,i) ((((i) & 0x7fff) << 16)|((t) & APM_EVENT_MASK))
+#define APM_EVENT_TYPE(e) ((e) & APM_EVENT_MASK)
+#define APM_EVENT_INDEX(e) ((e) >> 16)
+
+#define APM_GET_POWER_STATE 0x530c
+
+/*
+ * LP (Laptop Package)
+ *
+ * Copyright (C) 1994 by HOSOKAWA Tatsumi <hosokawa@mt.cs.keio.ac.jp>
+ *
+ * This software may be used, modified, copied, and distributed, in
+ * both source and binary form provided that the above copyright and
+ * these terms are retained. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with its
+ * use.
+ *
+ * Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
+ */
+
+#define APM_BATTERY_ABSENT 4
+
+struct apm_power_info {
+ u_char battery_state;
+ u_char ac_state;
+ u_char battery_life;
+ u_char spare1;
+ u_int minutes_left; /* estimate */
+ u_int spare2[6];
+};
+
+struct apm_ctl {
+ u_int dev;
+ u_int mode;
+};
+
+#define APM_IOC_STANDBY _IO('A', 1) /* put system into standby */
+#define APM_IOC_SUSPEND _IO('A', 2) /* put system into suspend */
+#define APM_IOC_GETPOWER _IOR('A', 3, struct apm_power_info) /* fetch battery state */
+#define APM_IOC_PRN_CTL _IOW('A', 6, int) /* driver power status msg */
+#define APM_PRINT_ON 0 /* driver power status displayed */
+#define APM_PRINT_OFF 1 /* driver power status not displayed */
+#define APM_PRINT_PCT 2 /* driver power status only displayed
+ if the percentage changes */
+
+#endif /* _MACHINE_APMVAR_H_ */
diff --git a/sys/arch/sparc/include/conf.h b/sys/arch/sparc/include/conf.h
index ee7e8d4298c..ca6a9d746b3 100644
--- a/sys/arch/sparc/include/conf.h
+++ b/sys/arch/sparc/include/conf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.h,v 1.18 2003/09/23 16:51:11 millert Exp $ */
+/* $OpenBSD: conf.h,v 1.19 2005/03/29 16:26:44 miod Exp $ */
/* $NetBSD: conf.h,v 1.8 1996/12/31 07:12:43 mrg Exp $ */
/*
@@ -105,3 +105,11 @@ cdev_decl(fga);
(dev_type_stop((*))) nullop, 0, seltrue, \
(dev_type_mmap((*))) enodev }
cdev_decl(daadio);
+
+/* open, close, write, ioctl, kqueue */
+#define cdev_apm_init(c,n) { \
+ dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
+ (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
+ (dev_type_stop((*))) enodev, 0, (dev_type_poll((*))) enodev, \
+ (dev_type_mmap((*))) enodev, D_KQFILTER, dev_init(c,n,kqfilter) }
+cdev_decl(apm);
diff --git a/sys/arch/sparc/sparc/conf.c b/sys/arch/sparc/sparc/conf.c
index d31d1b9ef47..b28d6eb002e 100644
--- a/sys/arch/sparc/sparc/conf.c
+++ b/sys/arch/sparc/sparc/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.39 2004/02/10 01:31:21 millert Exp $ */
+/* $OpenBSD: conf.c,v 1.40 2005/03/29 16:26:45 miod Exp $ */
/* $NetBSD: conf.c,v 1.40 1996/04/11 19:20:03 thorpej Exp $ */
/*
@@ -125,8 +125,8 @@ struct bdevsw bdevsw[] =
int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]);
#include "pf.h"
-
#include "systrace.h"
+#include "tctrl.h"
struct cdevsw cdevsw[] =
{
@@ -160,7 +160,7 @@ struct cdevsw cdevsw[] =
cdev_notdef(), /* 27: was /dev/bwtwo */
cdev_notdef(), /* 28 */
cdev_notdef(), /* 29: was /dev/kbd */
- cdev_notdef(), /* 30 */
+ cdev_apm_init(NTCTRL,apm), /* 30: tctrl APM interface */
cdev_notdef(), /* 31: was /dev/cgtwo */
cdev_notdef(), /* 32: should be /dev/gpone */
cdev_notdef(), /* 33 */