On Wed, Jul 05, 2023 at 04:53:33PM +0200, Tobias Heider wrote: > I am planning to restructure the APM/sleep APIs to make it easier to suspend > from more places like as a suspend keyboard shortcut. > > The acpiioctl handler is x86 specific code which is currently built on all > platforms but only hooked up on i386 and amd64. It is also in the way of > my plans, so I'd prefer if we move it to acpi_x86.c where all the other > x86-only acpi code lives. >
The previous diff wasn't enough to solve the problem and broke RAMDISK, so here's a next try. This moves anything /dev/apm related to the new acpi_apm.c file which is only included on i386 and amd64 and properly handles SMALL_KERNEL. Some apm related code (apm_apminfo, acpi_sleep_task) remains in acpi.c for now because it is also used by arm64 or called from MI paths. I plan to clean up the sleep task in the follow-up diff but this one is big enough already. Tested on amd64, i386, macppc and arm64 with GENERIC.MP and RAMDISK. Index: arch/amd64/conf/files.amd64 =================================================================== RCS file: /cvs/src/sys/arch/amd64/conf/files.amd64,v retrieving revision 1.108 diff -u -p -r1.108 files.amd64 --- arch/amd64/conf/files.amd64 26 Apr 2023 15:11:21 -0000 1.108 +++ arch/amd64/conf/files.amd64 7 Jul 2023 09:32:42 -0000 @@ -237,6 +237,7 @@ attach acpi at bios file arch/amd64/amd64/acpi_machdep.c acpi file arch/amd64/amd64/acpi_wakecode.S acpi & !small_kernel file dev/acpi/acpi_x86.c acpi & suspend & !small_kernel +file dev/acpi/acpi_apm.c acpi device acpipci attach acpipci at acpi Index: arch/i386/conf/files.i386 =================================================================== RCS file: /cvs/src/sys/arch/i386/conf/files.i386,v retrieving revision 1.249 diff -u -p -r1.249 files.i386 --- arch/i386/conf/files.i386 17 Jan 2023 10:10:11 -0000 1.249 +++ arch/i386/conf/files.i386 7 Jul 2023 09:32:42 -0000 @@ -377,6 +377,7 @@ attach acpi at bios file arch/i386/i386/acpi_machdep.c acpi file arch/i386/i386/acpi_wakecode.S acpi & !small_kernel file dev/acpi/acpi_x86.c acpi & suspend & !small_kernel +file dev/acpi/acpi_apm.c acpi # # IPMI Index: dev/acpi/acpi.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpi.c,v retrieving revision 1.424 diff -u -p -r1.424 acpi.c --- dev/acpi/acpi.c 7 Jul 2023 07:37:59 -0000 1.424 +++ dev/acpi/acpi.c 7 Jul 2023 09:32:42 -0000 @@ -28,10 +28,6 @@ #include <sys/kthread.h> #include <sys/sched.h> -#ifdef HIBERNATE -#include <sys/hibernate.h> -#endif - #include <machine/conf.h> #include <machine/cpufunc.h> @@ -47,10 +43,6 @@ #include <dev/pci/pciidevar.h> #include <machine/apmvar.h> -#define APMUNIT(dev) (minor(dev)&0xf0) -#define APMDEV(dev) (minor(dev)&0x0f) -#define APMDEV_NORMAL 0 -#define APMDEV_CTL 8 #include "wd.h" @@ -3384,134 +3376,6 @@ acpi_apminfo(struct apm_power_info *pi) return 0; } -int -acpiopen(dev_t dev, int flag, int mode, struct proc *p) -{ - int error = 0; - struct acpi_softc *sc; - int s; - - if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || - !(sc = acpi_cd.cd_devs[APMUNIT(dev)])) - return (ENXIO); - - s = splbio(); - switch (APMDEV(dev)) { - case APMDEV_CTL: - if (!(flag & FWRITE)) { - error = EINVAL; - break; - } - if (sc->sc_flags & SCFLAG_OWRITE) { - error = EBUSY; - break; - } - sc->sc_flags |= SCFLAG_OWRITE; - break; - case APMDEV_NORMAL: - if (!(flag & FREAD) || (flag & FWRITE)) { - error = EINVAL; - break; - } - sc->sc_flags |= SCFLAG_OREAD; - break; - default: - error = ENXIO; - break; - } - splx(s); - return (error); -} - -int -acpiclose(dev_t dev, int flag, int mode, struct proc *p) -{ - int error = 0; - struct acpi_softc *sc; - int s; - - if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || - !(sc = acpi_cd.cd_devs[APMUNIT(dev)])) - return (ENXIO); - - s = splbio(); - switch (APMDEV(dev)) { - case APMDEV_CTL: - sc->sc_flags &= ~SCFLAG_OWRITE; - break; - case APMDEV_NORMAL: - sc->sc_flags &= ~SCFLAG_OREAD; - break; - default: - error = ENXIO; - break; - } - splx(s); - return (error); -} - -int -acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) -{ - int error = 0; - struct acpi_softc *sc; - struct apm_power_info *pi = (struct apm_power_info *)data; - int s; - - if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || - !(sc = acpi_cd.cd_devs[APMUNIT(dev)])) - return (ENXIO); - - s = splbio(); - /* fake APM */ - switch (cmd) { - case APM_IOC_SUSPEND: - case APM_IOC_STANDBY: - if ((flag & FWRITE) == 0) { - error = EBADF; - break; - } - acpi_addtask(sc, acpi_sleep_task, sc, SLEEP_SUSPEND); - acpi_wakeup(sc); - break; -#ifdef HIBERNATE - case APM_IOC_HIBERNATE: - if ((error = suser(p)) != 0) - break; - if ((flag & FWRITE) == 0) { - error = EBADF; - break; - } - if (get_hibernate_io_function(swdevt[0].sw_dev) == NULL) { - error = EOPNOTSUPP; - break; - } - acpi_addtask(sc, acpi_sleep_task, sc, SLEEP_HIBERNATE); - acpi_wakeup(sc); - break; -#endif - case APM_IOC_GETPOWER: - error = acpi_apminfo(pi); - break; - - default: - error = ENOTTY; - } - - splx(s); - return (error); -} - -void acpi_filtdetach(struct knote *); -int acpi_filtread(struct knote *, long); - -const struct filterops acpiread_filtops = { - .f_flags = FILTEROP_ISFD, - .f_attach = NULL, - .f_detach = acpi_filtdetach, - .f_event = acpi_filtread, -}; - int acpi_evindex; int @@ -3523,79 +3387,6 @@ acpi_record_event(struct acpi_softc *sc, acpi_evindex++; knote_locked(&sc->sc_note, APM_EVENT_COMPOSE(type, acpi_evindex)); return (0); -} - -void -acpi_filtdetach(struct knote *kn) -{ - struct acpi_softc *sc = kn->kn_hook; - int s; - - s = splbio(); - klist_remove_locked(&sc->sc_note, kn); - splx(s); -} - -int -acpi_filtread(struct knote *kn, long hint) -{ - /* XXX weird kqueue_scan() semantics */ - if (hint && !kn->kn_data) - kn->kn_data = hint; - return (1); -} - -int -acpikqfilter(dev_t dev, struct knote *kn) -{ - struct acpi_softc *sc; - int s; - - if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || - !(sc = acpi_cd.cd_devs[APMUNIT(dev)])) - return (ENXIO); - - switch (kn->kn_filter) { - case EVFILT_READ: - kn->kn_fop = &acpiread_filtops; - break; - default: - return (EINVAL); - } - - kn->kn_hook = sc; - - s = splbio(); - klist_insert_locked(&sc->sc_note, kn); - splx(s); - - return (0); -} - -#else /* SMALL_KERNEL */ - -int -acpiopen(dev_t dev, int flag, int mode, struct proc *p) -{ - return (ENXIO); -} - -int -acpiclose(dev_t dev, int flag, int mode, struct proc *p) -{ - return (ENXIO); -} - -int -acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) -{ - return (ENXIO); -} - -int -acpikqfilter(dev_t dev, struct knote *kn) -{ - return (EOPNOTSUPP); } #endif /* SMALL_KERNEL */ Index: dev/acpi/acpi_apm.c =================================================================== RCS file: dev/acpi/acpi_apm.c diff -N dev/acpi/acpi_apm.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ dev/acpi/acpi_apm.c 7 Jul 2023 09:32:42 -0000 @@ -0,0 +1,228 @@ +/* $OpenBSD$ */ +/* + * Copyright (c) 2005 Thorsten Lockert <th...@sigmasoft.com> + * Copyright (c) 2005 Jordan Hargrave <jor...@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/fcntl.h> + +#include <dev/acpi/acpireg.h> +#include <dev/acpi/acpivar.h> +#include <dev/acpi/acpidev.h> +#include <dev/acpi/dsdt.h> + +#include <machine/conf.h> +#include <machine/cpufunc.h> + +#ifdef HIBERNATE +#include <sys/hibernate.h> +#endif + +#include <machine/apmvar.h> +#define APMUNIT(dev) (minor(dev)&0xf0) +#define APMDEV(dev) (minor(dev)&0x0f) +#define APMDEV_NORMAL 0 +#define APMDEV_CTL 8 + +#ifndef SMALL_KERNEL + +int +acpiopen(dev_t dev, int flag, int mode, struct proc *p) +{ + int error = 0; + struct acpi_softc *sc = acpi_softc; + int s; + + s = splbio(); + switch (APMDEV(dev)) { + case APMDEV_CTL: + if (!(flag & FWRITE)) { + error = EINVAL; + break; + } + if (sc->sc_flags & SCFLAG_OWRITE) { + error = EBUSY; + break; + } + sc->sc_flags |= SCFLAG_OWRITE; + break; + case APMDEV_NORMAL: + if (!(flag & FREAD) || (flag & FWRITE)) { + error = EINVAL; + break; + } + sc->sc_flags |= SCFLAG_OREAD; + break; + default: + error = ENXIO; + break; + } + splx(s); + return (error); +} + +int +acpiclose(dev_t dev, int flag, int mode, struct proc *p) +{ + int error = 0; + struct acpi_softc *sc = acpi_softc; + int s; + + s = splbio(); + switch (APMDEV(dev)) { + case APMDEV_CTL: + sc->sc_flags &= ~SCFLAG_OWRITE; + break; + case APMDEV_NORMAL: + sc->sc_flags &= ~SCFLAG_OREAD; + break; + default: + error = ENXIO; + break; + } + splx(s); + return (error); +} + +int +acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + int error = 0; + struct acpi_softc *sc = acpi_softc; + struct apm_power_info *pi = (struct apm_power_info *)data; + int s; + + s = splbio(); + /* fake APM */ + switch (cmd) { + case APM_IOC_SUSPEND: + case APM_IOC_STANDBY: + if ((flag & FWRITE) == 0) { + error = EBADF; + break; + } + acpi_addtask(sc, acpi_sleep_task, sc, SLEEP_SUSPEND); + acpi_wakeup(sc); + break; +#ifdef HIBERNATE + case APM_IOC_HIBERNATE: + if ((error = suser(p)) != 0) + break; + if ((flag & FWRITE) == 0) { + error = EBADF; + break; + } + if (get_hibernate_io_function(swdevt[0].sw_dev) == NULL) { + error = EOPNOTSUPP; + break; + } + acpi_addtask(sc, acpi_sleep_task, sc, SLEEP_HIBERNATE); + acpi_wakeup(sc); + break; +#endif + case APM_IOC_GETPOWER: + error = acpi_apminfo(pi); + break; + + default: + error = ENOTTY; + } + + splx(s); + return (error); +} + +void acpi_filtdetach(struct knote *); +int acpi_filtread(struct knote *, long); + +const struct filterops acpiread_filtops = { + .f_flags = FILTEROP_ISFD, + .f_attach = NULL, + .f_detach = acpi_filtdetach, + .f_event = acpi_filtread, +}; + +int +acpikqfilter(dev_t dev, struct knote *kn) +{ + struct acpi_softc *sc = acpi_softc; + int s; + + switch (kn->kn_filter) { + case EVFILT_READ: + kn->kn_fop = &acpiread_filtops; + break; + default: + return (EINVAL); + } + + kn->kn_hook = sc; + + s = splbio(); + klist_insert_locked(&sc->sc_note, kn); + splx(s); + + return (0); +} + +void +acpi_filtdetach(struct knote *kn) +{ + struct acpi_softc *sc = kn->kn_hook; + int s; + + s = splbio(); + klist_remove_locked(&sc->sc_note, kn); + splx(s); +} + +int +acpi_filtread(struct knote *kn, long hint) +{ + /* XXX weird kqueue_scan() semantics */ + if (hint && !kn->kn_data) + kn->kn_data = hint; + return (1); +} + +#else /* SMALL_KERNEL */ + +int +acpiopen(dev_t dev, int flag, int mode, struct proc *p) +{ + return (ENXIO); +} + +int +acpiclose(dev_t dev, int flag, int mode, struct proc *p) +{ + return (ENXIO); +} + +int +acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + return (ENXIO); +} + +int +acpikqfilter(dev_t dev, struct knote *kn) +{ + return (EOPNOTSUPP); +} + +#endif /* SMALL_KERNEL */