> Date: Sat, 8 Jul 2023 10:10:51 +0200 > From: Tobias Heider <tobias.hei...@stusta.de> > > This diff adds request_sleep(), a MI way of sending the machine to sleep in a > safe thread. Support is limited to amd64, i386 and arm64 at the moment, macppc > is currently an empty stub since it doesn't implement a sleep task (yet). > > Once this works, my next plan is adding a Ks_Cmd_Sleep keybinding that is > handled > in wskbd to get the suspend button working on my m2. > > I also tested this on a bunch of different archs and kernel configs. > > ok?
Should the macppc version return EOPNOTSUPP? > diff 6c06be8c9470ada9d77f3ea989b6ed3d857ec4e6 > a896f4652f8b00e4f2bbd64d751c85560c264222 > commit - 6c06be8c9470ada9d77f3ea989b6ed3d857ec4e6 > commit + a896f4652f8b00e4f2bbd64d751c85560c264222 > blob - 63d45d3697e4093cf5751308851d470bf5dc62bb > blob + 721d18a4ae212c80f44313a3cd27f4191146c3d6 > --- sys/arch/arm64/dev/aplsmc.c > +++ sys/arch/arm64/dev/aplsmc.c > @@ -366,7 +366,6 @@ aplsmc_handle_notification(struct aplsmc_softc *sc, ui > extern int allowpowerdown; > #ifdef SUSPEND > extern int cpu_suspended; > - extern void suspend(void); > > if (cpu_suspended) { > switch (SMC_EV_TYPE(data)) { > @@ -433,7 +432,7 @@ aplsmc_handle_notification(struct aplsmc_softc *sc, ui > } > case 1: > #ifdef SUSPEND > - suspend(); > + request_sleep(SLEEP_SUSPEND); > #endif > break; > case 2: > blob - 2ccc822991480c6b4f4dd44f263ac945a141a6bf > blob + 4491ca380d08182244a8157874fc51bcc9665f26 > --- sys/arch/arm64/dev/apm.c > +++ sys/arch/arm64/dev/apm.c > @@ -57,11 +57,14 @@ struct taskq *suspend_taskq; > #endif > > #ifdef SUSPEND > -struct taskq *suspend_taskq; > +struct taskq *sleep_taskq; > struct task suspend_task; > void do_suspend(void *); > -void suspend(void); > +#ifdef HIBERNATE > +struct task hibernate_task; > +void do_hibernate(void *); > #endif > +#endif > > struct apm_softc { > struct device sc_dev; > @@ -128,9 +131,12 @@ apmattach(struct device *parent, struct device *self, > apmattach(struct device *parent, struct device *self, void *aux) > { > #ifdef SUSPEND > - suspend_taskq = taskq_create("suspend", 1, IPL_NONE, 0); > + sleep_taskq = taskq_create("sleep", 1, IPL_NONE, 0); > task_set(&suspend_task, do_suspend, NULL); > +#ifdef HIBERNATE > + task_set(&hibernate_task, do_hibernate, NULL); > #endif > +#endif > > acpiapm_open = apmopen; > acpiapm_close = apmclose; > @@ -224,7 +230,7 @@ apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag > error = EBADF; > break; > } > - suspend(); > + error = request_sleep(SLEEP_SUSPEND); > break; > #ifdef HIBERNATE > case APM_IOC_HIBERNATE: > @@ -234,11 +240,7 @@ apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag > error = EBADF; > break; > } > - if (get_hibernate_io_function(swdevt[0].sw_dev) == NULL) { > - error = EOPNOTSUPP; > - break; > - } > - sleep_state(NULL, SLEEP_HIBERNATE); > + error = request_sleep(SLEEP_HIBERNATE); > break; > #endif > #endif > @@ -358,13 +360,36 @@ void > sleep_state(v, SLEEP_SUSPEND); > } > > +#ifdef HIBERNATE > void > -suspend(void) > +do_hibernate(void *v) > { > - if (suspend_taskq) > - task_add(suspend_taskq, &suspend_task); > + sleep_state(v, SLEEP_HIBERNATE); > } > +#endif > > +int > +request_sleep(int sleepmode) > +{ > + if (sleep_taskq == NULL) > + return EINVAL; > + > + switch (sleepmode) { > + case SLEEP_SUSPEND: > + task_add(sleep_taskq, &suspend_task); > + break; > +#ifdef HIBERNATE > + case SLEEP_HIBERNATE: > + if (get_hibernate_io_function(swdevt[0].sw_dev) == NULL) > + return EOPNOTSUPP; > + task_add(sleep_taskq, &hibernate_task); > + break; > +#endif > + } > + > + return 0; > +} > + > #ifdef MULTIPROCESSOR > > void > blob - 9082d868f963b80cf0f64453914146a980020883 > blob + 52166ca3bfcb826f8c47835024804e5d59061f96 > --- sys/arch/macppc/dev/apm.c > +++ sys/arch/macppc/dev/apm.c > @@ -337,6 +337,12 @@ apmkqfilter(dev_t dev, struct knote *kn) > > #ifdef SUSPEND > > +int > +request_sleep(int sleepmode) > +{ > + return 0; > +} > + > #ifdef MULTIPROCESSOR > > void > blob - f7d59513aad484983a8932671c1d06fb4474f550 > blob + 59adebc66708d6a1d1c2168e6d01675ae776dca3 > --- sys/dev/acpi/acpi_apm.c > +++ sys/dev/acpi/acpi_apm.c > @@ -109,13 +109,16 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t data, int fla > s = splbio(); > /* fake APM */ > switch (cmd) { > +#ifdef SUSPEND > case APM_IOC_SUSPEND: > case APM_IOC_STANDBY: > if ((flag & FWRITE) == 0) { > error = EBADF; > break; > } > - acpi_addtask(sc, acpi_sleep_task, sc, SLEEP_SUSPEND); > + error = request_sleep(SLEEP_SUSPEND); > + if (error) > + break; > acpi_wakeup(sc); > break; > #ifdef HIBERNATE > @@ -130,10 +133,13 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t data, int fla > error = EOPNOTSUPP; > break; > } > - acpi_addtask(sc, acpi_sleep_task, sc, SLEEP_HIBERNATE); > + error = request_sleep(SLEEP_HIBERNATE); > + if (error) > + break; > acpi_wakeup(sc); > break; > #endif > +#endif > case APM_IOC_GETPOWER: > error = acpi_apminfo(pi); > break; > @@ -199,6 +205,23 @@ acpi_filtread(struct knote *kn, long hint) > return (1); > } > > +#ifdef SUSPEND > +int > +request_sleep(int sleepmode) > +{ > + struct acpi_softc *sc = acpi_softc; > + > +#ifdef HIBERNATE > + if (sleepmode == SLEEP_HIBERNATE) { > + if (get_hibernate_io_function(swdevt[0].sw_dev) == NULL) > + return EOPNOTSUPP; > + } > +#endif > + acpi_addtask(sc, acpi_sleep_task, sc, sleepmode); > + return 0; > +} > +#endif /* SUSPEND */ > + > #else /* SMALL_KERNEL */ > > int > blob - e99f2d75e16f5c5299e5819fbc20c48fca7c4524 > blob + f545bdf5043d51c519765055d5bde6d73b429f3d > --- sys/sys/device.h > +++ sys/sys/device.h > @@ -199,6 +199,7 @@ int sleep_state(void *, int); > void config_mountroot(struct device *, void (*)(struct device *)); > void config_process_deferred_mountroot(void); > > +int request_sleep(int); > int sleep_state(void *, int); > #define SLEEP_SUSPEND 0x01 > #define SLEEP_HIBERNATE 0x02 > >