summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2001-08-18 06:08:09 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2001-08-18 06:08:09 +0000
commit49227549413b4f17e45ca23767bc3c3ef2cba81c (patch)
tree8f10e0babd3459a35d71ab6ea2bb41b89809e90a /sys/arch/i386
parent080c67550fc82814a4fbea565daca7ebf54c6286 (diff)
make apm use kqueue for transferring events to luse listener.
apparently i thought i comitted this already before apmd. tested by me, art@ and jason@ .
Diffstat (limited to 'sys/arch/i386')
-rw-r--r--sys/arch/i386/i386/apm.c149
-rw-r--r--sys/arch/i386/i386/conf.c4
-rw-r--r--sys/arch/i386/include/apmvar.h16
-rw-r--r--sys/arch/i386/include/conf.h8
4 files changed, 87 insertions, 90 deletions
diff --git a/sys/arch/i386/i386/apm.c b/sys/arch/i386/i386/apm.c
index ca6b9f5e305..1cd2521536b 100644
--- a/sys/arch/i386/i386/apm.c
+++ b/sys/arch/i386/i386/apm.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: apm.c,v 1.48 2001/06/24 20:38:04 fgsch Exp $ */
+/* $OpenBSD: apm.c,v 1.49 2001/08/18 06:08:08 mickey Exp $ */
/*-
- * Copyright (c) 1998-2000 Michael Shalayeff. All rights reserved.
+ * 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
@@ -53,6 +53,7 @@
#include <sys/device.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
+#include <sys/event.h>
#include <sys/mount.h> /* for vfs_syncwait() proto */
#include <machine/conf.h>
@@ -78,25 +79,15 @@
#define APM_LOCK(sc) lockmgr(&(sc)->sc_lock, LK_EXCLUSIVE, NULL, curproc)
#define APM_UNLOCK(sc) lockmgr(&(sc)->sc_lock, LK_RELEASE, NULL, curproc)
-int apmprobe __P((struct device *, void *, void *));
-void apmattach __P((struct device *, struct device *, void *));
-
-/* battery percentage at where we get verbose in our warnings. This
- value can be changed using sysctl(8), value machdep.apmwarn.
- Setting it to zero kills all warnings */
-int cpu_apmwarn = 10;
-
-#define APM_NEVENTS 16
-#define APM_RESUME_HOLDOFF 3
+struct cfdriver apm_cd = {
+ NULL, "apm", DV_DULL
+};
struct apm_softc {
struct device sc_dev;
- struct selinfo sc_rsel;
+ struct klist sc_note;
int sc_flags;
int batt_life;
- int event_count;
- int event_ptr;
- struct apm_event_info event_list[APM_NEVENTS];
struct proc *sc_thread;
struct lock sc_lock;
};
@@ -104,6 +95,26 @@ struct apm_softc {
#define SCFLAG_OWRITE 0x0000002
#define SCFLAG_OPEN (SCFLAG_OREAD|SCFLAG_OWRITE)
+int apmprobe __P((struct device *, void *, void *));
+void apmattach __P((struct device *, struct device *, void *));
+
+struct cfattach apm_ca = {
+ sizeof(struct apm_softc), apmprobe, apmattach
+};
+
+void filt_apmrdetach __P((struct knote *kn));
+int filt_apmread __P((struct knote *kn, long hint));
+
+struct filterops apmread_filtops =
+ { 1, NULL, filt_apmrdetach, filt_apmread};
+
+/* battery percentage at where we get verbose in our warnings. This
+ value can be changed using sysctl(8), value machdep.apmwarn.
+ Setting it to zero kills all warnings */
+int cpu_apmwarn = 10;
+
+#define APM_RESUME_HOLDOFF 3
+
/*
* Flags to control kernel display
* SCFLAG_NOPRINT: do not output APM power messages due to
@@ -122,14 +133,6 @@ struct apm_softc {
#define APMDEV_NORMAL 0
#define APMDEV_CTL 8
-struct cfattach apm_ca = {
- sizeof(struct apm_softc), apmprobe, apmattach
-};
-
-struct cfdriver apm_cd = {
- NULL, "apm", DV_DULL
-};
-
int apm_standbys;
int apm_userstandbys;
int apm_suspends;
@@ -170,7 +173,7 @@ void apm_perror __P((const char *, struct apmregs *));
void apm_powmgt_enable __P((int onoff));
void apm_powmgt_engage __P((int onoff, u_int devid));
/* void apm_devpowmgt_enable __P((int onoff, u_int devid)); */
-int apm_record_event __P((struct apm_softc *sc, u_int event_type));
+int apm_record_event __P((struct apm_softc *sc, u_int type));
const char *apm_err_translate __P((int code));
#define apm_get_powstat(r) apmcall(APM_POWER_STATUS, APM_DEV_ALLDEVS, r)
@@ -343,9 +346,6 @@ apm_resume(sc, regs)
{
apm_resumes = APM_RESUME_HOLDOFF;
- /* flush the event queue */
- sc->event_count = 0;
-
/* they say that some machines may require reinitializing the clock */
initrtclock();
@@ -359,34 +359,20 @@ apm_resume(sc, regs)
}
int
-apm_record_event(sc, event_type)
+apm_record_event(sc, type)
struct apm_softc *sc;
- u_int event_type;
+ u_int type;
{
- struct apm_event_info *evp;
-
if (!apm_error && (sc->sc_flags & SCFLAG_OPEN) == 0) {
DPRINTF(("apm_record_event: no user waiting\n"));
apm_error++;
return 1;
}
- if (sc->event_count >= APM_NEVENTS) {
- DPRINTF(("apm_record_event: overflow\n"));
- apm_error++;
- } else {
- int s = splhigh();
- evp = &sc->event_list[sc->event_ptr];
- sc->event_count++;
- sc->event_ptr++;
- sc->event_ptr %= APM_NEVENTS;
- evp->type = event_type;
- evp->index = ++apm_evindex;
- splx(s);
- }
- selwakeup(&sc->sc_rsel);
+ apm_evindex++;
+ KNOTE(&sc->sc_note, APM_EVENT_COMPOSE(type, apm_evindex));
- return (sc->sc_flags & SCFLAG_OWRITE) ? 0 : 1; /* user may handle */
+ return (0);
}
int
@@ -994,10 +980,6 @@ apmclose(dev, flag, mode, p)
sc->sc_flags &= ~SCFLAG_OREAD;
break;
}
- if ((sc->sc_flags & SCFLAG_OPEN) == 0) {
- sc->event_count = 0;
- sc->event_ptr = 0;
- }
APM_UNLOCK(sc);
return 0;
}
@@ -1012,7 +994,7 @@ apmioctl(dev, cmd, data, flag, p)
{
struct apm_softc *sc;
struct apmregs regs;
- int i, error = 0;
+ int error = 0;
/* apm0 only */
if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
@@ -1072,17 +1054,6 @@ apmioctl(dev, cmd, data, flag, p)
error = apm_set_powstate(actl->dev, actl->mode);
}
break;
- case APM_IOC_NEXTEVENT:
- if (sc->event_count) {
- struct apm_event_info *evp =
- (struct apm_event_info *)data;
- i = sc->event_ptr + APM_NEVENTS - sc->event_count;
- i %= APM_NEVENTS;
- *evp = sc->event_list[i];
- sc->event_count--;
- } else
- error = EAGAIN;
- break;
case APM_IOC_GETPOWER:
if (apm_get_powstat(&regs) == 0) {
struct apm_power_info *powerp =
@@ -1128,32 +1099,54 @@ apmioctl(dev, cmd, data, flag, p)
return error;
}
+void
+filt_apmrdetach(kn)
+ struct knote *kn;
+{
+ struct apm_softc *sc = (struct apm_softc *)kn->kn_hook;
+
+ APM_LOCK(sc);
+ SLIST_REMOVE(&sc->sc_note, kn, knote, kn_selnext);
+ APM_UNLOCK(sc);
+}
+
int
-apmselect(dev, rw, p)
+filt_apmread(kn, hint)
+ 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, kn)
dev_t dev;
- int rw;
- struct proc *p;
+ struct knote *kn;
{
struct apm_softc *sc;
- int ret = 0;
/* apm0 only */
if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
!(sc = apm_cd.cd_devs[APMUNIT(dev)]))
return ENXIO;
- APM_LOCK(sc);
- switch (rw) {
- case FREAD:
- if (sc->event_count)
- ret++;
- else
- selrecord(p, &sc->sc_rsel);
- break;
- case FWRITE:
- case 0:
+ switch (kn->kn_filter) {
+ case EVFILT_READ:
+ kn->kn_fop = &apmread_filtops;
break;
+ default:
+ return (1);
}
+
+ kn->kn_hook = (caddr_t)sc;
+
+ APM_LOCK(sc);
+ SLIST_INSERT_HEAD(&sc->sc_note, kn, kn_selnext);
APM_UNLOCK(sc);
- return ret;
+
+ return (0);
}
diff --git a/sys/arch/i386/i386/conf.c b/sys/arch/i386/i386/conf.c
index cb09ad494b4..3214f21ceda 100644
--- a/sys/arch/i386/i386/conf.c
+++ b/sys/arch/i386/i386/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.78 2001/08/06 22:34:43 mickey Exp $ */
+/* $OpenBSD: conf.c,v 1.79 2001/08/18 06:08:08 mickey Exp $ */
/* $NetBSD: conf.c,v 1.75 1996/05/03 19:40:20 christos Exp $ */
/*
@@ -272,7 +272,7 @@ struct cdevsw cdevsw[] =
cdev_disk_init(NCCD,ccd), /* 18: concatenated disk driver */
cdev_ss_init(NSS,ss), /* 19: SCSI scanner */
cdev_uk_init(NUK,uk), /* 20: unknown SCSI */
- cdev_ocis_init(NAPM,apm), /* 21: Advancded Power Management */
+ cdev_apm_init(NAPM,apm), /* 21: Advancded Power Management */
cdev_fd_init(1,filedesc), /* 22: file descriptor pseudo-device */
cdev_bpftun_init(NBPFILTER,bpf),/* 23: Berkeley packet filter */
cdev_ses_init(NSES,ses), /* 24: SES/SAF-TE SCSI */
diff --git a/sys/arch/i386/include/apmvar.h b/sys/arch/i386/include/apmvar.h
index 6f313844fdb..23ec88eab43 100644
--- a/sys/arch/i386/include/apmvar.h
+++ b/sys/arch/i386/include/apmvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: apmvar.h,v 1.12 2001/06/24 21:17:33 mickey Exp $ */
+/* $OpenBSD: apmvar.h,v 1.13 2001/08/18 06:08:08 mickey Exp $ */
/*
* Copyright (c) 1995 John T. Kohl
@@ -174,7 +174,11 @@
/* 0x0100 - 0x01ff Reserved device events */
/* 0x0200 - 0x02ff OEM-defined APM events */
/* 0x0300 - 0xffff Reserved */
-#define APM_DEFEVENT 0xffffffff /* for customization */
+#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
#define APM_DEVICE_MGMT_ENABLE 0x530d
@@ -256,12 +260,6 @@
* Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
*/
-struct apm_event_info {
- u_int type;
- u_int index;
- u_int spare[8];
-};
-
#define APM_BATTERY_ABSENT 4
struct apm_power_info {
@@ -282,7 +280,6 @@ struct apm_ctl {
#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_NEXTEVENT _IOR('A', 4, struct apm_event_info) /* fetch event */
#define APM_IOC_DEV_CTL _IOW('A', 5, struct apm_ctl) /* put device into mode */
#define APM_IOC_PRN_CTL _IOW('A', 6, int ) /* driver power status msg */
#define APM_PRINT_ON 0 /* driver power status displayed */
@@ -295,6 +292,7 @@ extern void apm_cpu_busy __P((void));
extern void apm_cpu_idle __P((void));
extern void apminit __P((void));
int apm_set_powstate __P((u_int devid, u_int powstate));
+int apm_kqfilter __P((dev_t dev, struct knote *kn));
#endif /* _KERNEL */
#endif /* _I386_APMVAR_H_ */
diff --git a/sys/arch/i386/include/conf.h b/sys/arch/i386/include/conf.h
index 0646f0e604a..ae3ef445ee5 100644
--- a/sys/arch/i386/include/conf.h
+++ b/sys/arch/i386/include/conf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.h,v 1.7 1997/09/27 06:31:32 mickey Exp $ */
+/* $OpenBSD: conf.h,v 1.8 2001/08/18 06:08:08 mickey Exp $ */
/* $NetBSD: conf.h,v 1.2 1996/05/05 19:28:34 christos Exp $ */
/*
@@ -54,6 +54,12 @@ cdev_decl(pc);
dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \
0, seltrue, (dev_type_mmap((*))) enodev }
+#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_select((*))) enodev, \
+ (dev_type_mmap((*))) enodev, D_KQFILTER, dev_init(c,n,kqfilter) }
+
cdev_decl(spkr);
cdev_decl(mms);