diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2001-08-18 06:08:09 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2001-08-18 06:08:09 +0000 |
commit | 49227549413b4f17e45ca23767bc3c3ef2cba81c (patch) | |
tree | 8f10e0babd3459a35d71ab6ea2bb41b89809e90a /sys/arch/i386 | |
parent | 080c67550fc82814a4fbea565daca7ebf54c6286 (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.c | 149 | ||||
-rw-r--r-- | sys/arch/i386/i386/conf.c | 4 | ||||
-rw-r--r-- | sys/arch/i386/include/apmvar.h | 16 | ||||
-rw-r--r-- | sys/arch/i386/include/conf.h | 8 |
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(®s) == 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); |