On 2023 Jul 08 (Sat) at 13:09:00 +0300 (+0300), Tobias Heider wrote: : : :On July 8, 2023 11:36:21 AM GMT+03:00, Mark Kettenis <mark.kette...@xs4all.nl> wrote: :>> 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? : :Sure, sounds a bit more descriptive. :
OK :> :>> 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 :>> :>> : -- The best defense against logic is ignorance.