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.
>
>> 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
>>
>>