> Date: Fri, 7 Jul 2023 11:56:42 +0200
> From: Tobias Heider <[email protected]>
>
> 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.
ok kettenis@
> 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 <[email protected]>
> + * Copyright (c) 2005 Jordan Hargrave <[email protected]>
> + *
> + * 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 */
>
>