This diff has been sitting in my patches folder for weeks now - posting it now for discussion. What it does is to extend the machdep.lidsuspend sysctl to also cover hibernate. I think it might be interesting for users of a laptop/netbook where suspend tends to drain the battery, like my MSI Wind U100 does. Unfortunately The U100 doesn't even report lid status, but that's another story...
The machdep.lidsuspend sysctl is currently used like this: The value zero does nothing and every other value causes the system to suspend when the lid is being closed. I propose slightly different semantics: The value zero does nothing (as before), the value one causes the system to suspend (as before) and the value two initiates hibernation. All other values do not cause any effect. cheers, natano (tested on my Thinkpad T520 / amd64) Index: etc/etc.amd64/sysctl.conf =================================================================== RCS file: /cvs/src/etc/etc.amd64/sysctl.conf,v retrieving revision 1.6 diff -u -p -u -r1.6 sysctl.conf --- etc/etc.amd64/sysctl.conf 16 Jun 2015 20:30:24 -0000 1.6 +++ etc/etc.amd64/sysctl.conf 12 Oct 2015 20:44:39 -0000 @@ -1,3 +1,4 @@ #machdep.allowaperture=2 # See xf86(4) #machdep.kbdreset=1 # permit console CTRL-ALT-DEL to do a nice halt #machdep.lidsuspend=0 # do not suspend laptop upon lid closing +#machdep.lidsuspend=2 # put system into hibernation upon lid closing Index: etc/etc.i386/sysctl.conf =================================================================== RCS file: /cvs/src/etc/etc.i386/sysctl.conf,v retrieving revision 1.18 diff -u -p -u -r1.18 sysctl.conf --- etc/etc.i386/sysctl.conf 16 Jun 2015 20:30:24 -0000 1.18 +++ etc/etc.i386/sysctl.conf 12 Oct 2015 20:44:39 -0000 @@ -2,6 +2,7 @@ #machdep.apmhalt=1 # 1=powerdown hack, try if halt -p doesn't work #machdep.kbdreset=1 # permit console CTRL-ALT-DEL to do a nice halt #machdep.lidsuspend=0 # do not suspend laptop upon lid closing +#machdep.lidsuspend=2 # put system into hibernation upon lid closing #machdep.userldt=1 # allow userland programs to play with ldt, # required by some ports #kern.emul.linux=1 # enable running Linux binaries Index: sys/dev/acpi/acpibtn.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpibtn.c,v retrieving revision 1.41 diff -u -p -u -r1.41 acpibtn.c --- sys/dev/acpi/acpibtn.c 27 Jan 2015 19:40:14 -0000 1.41 +++ sys/dev/acpi/acpibtn.c 12 Oct 2015 20:44:49 -0000 @@ -16,11 +16,16 @@ */ #include <sys/param.h> +#include <sys/conf.h> #include <sys/signalvar.h> #include <sys/systm.h> #include <sys/device.h> #include <sys/malloc.h> +#ifdef HIBERNATE +#include <sys/hibernate.h> +#endif + #include <machine/bus.h> #include <machine/apmvar.h> @@ -225,10 +230,28 @@ acpibtn_notify(struct aml_node *node, in "_LID", 0, NULL, &lid)) return (0); sc->sc_sens.value = lid; - if (lid_suspend == 0) + + if (lid != 0) break; - if (lid == 0) + + switch (lid_suspend) { + case 1: goto sleep; +#ifdef HIBERNATE + case 2: + if (get_hibernate_io_function(swdevt[0].sw_dev) == NULL) + return (EOPNOTSUPP); + + /* Request to go to hibernation */ + if (acpi_record_event(sc->sc_acpi, APM_USER_HIBERNATE_REQ)) + acpi_addtask(sc->sc_acpi, acpi_sleep_task, + sc->sc_acpi, ACPI_STATE_S4); + break; +#endif /* HIBERNATE */ + case 0: + default: + break; + } #endif /* SMALL_KERNEL */ break; case ACPIBTN_SLEEP: