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 */

Reply via email to