Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F105769904
D18506.id51885.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D18506.id51885.diff
View Options
Index: share/man/man9/efirt.9
===================================================================
--- share/man/man9/efirt.9
+++ share/man/man9/efirt.9
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 12, 2018
+.Dd December 11, 2018
.Dt EFIRT 9
.Os
.Sh NAME
@@ -54,7 +54,7 @@
.Ft int
.Fn efi_get_time_capabilities "struct efi_tmcap *tmcap"
.Ft int
-.Fn efi_reset_system "void"
+.Fn efi_reset_system "enum efi_reset type"
.Ft int
.Fn efi_set_time "struct efi_tm *tm"
.Ft int
@@ -123,7 +123,20 @@
.Pp
The
.Fn efi_reset_system
-function requests a warm reset and reboot of the system.
+function requests a reset of the system.
+The
+.Fa type
+argument may be one of the
+.Vt enum efi_reset
+values:
+.Bl -tag -width ".Dv EFI_RESET_SHUTDOWN"
+.It Dv EFI_RESET_COLD
+Perform a cold reset of the system, and reboot.
+.It Dv EFI_RESET_WARM
+Perform a warm reset of the system, and reboot.
+.It Dv EFI_RESET_SHUTDOWN
+Power off the system.
+.El
.Pp
The
.Fn efi_set_time
@@ -239,7 +252,7 @@
.It Dv EROFS
The variable in question is read-only or may not be deleted.
.It Dv EDOOFUS
-The varialbe could not be set due to an authentication failure.
+The variable could not be set due to an authentication failure.
.It Dv ENOENT
The variable trying to be updated or deleted was not found.
.El
Index: sys/dev/efidev/efirt.c
===================================================================
--- sys/dev/efidev/efirt.c
+++ sys/dev/efidev/efirt.c
@@ -34,6 +34,7 @@
#include <sys/param.h>
#include <sys/efi.h>
+#include <sys/eventhandler.h>
#include <sys/kernel.h>
#include <sys/linker.h>
#include <sys/lock.h>
@@ -41,6 +42,7 @@
#include <sys/mutex.h>
#include <sys/clock.h>
#include <sys/proc.h>
+#include <sys/reboot.h>
#include <sys/rwlock.h>
#include <sys/sched.h>
#include <sys/sysctl.h>
@@ -106,6 +108,10 @@
}
static struct mtx efi_lock;
+static SYSCTL_NODE(_hw, OID_AUTO, efi, CTLFLAG_RWTUN, NULL, "EFI");
+static bool efi_poweroff = true;
+SYSCTL_BOOL(_hw_efi, OID_AUTO, poweroff, CTLFLAG_RWTUN, &efi_poweroff, 0,
+ "If true, use EFI runtime services to power off in preference to ACPI");
static bool
efi_is_in_map(struct efi_md *map, int ndesc, int descsz, vm_offset_t addr)
@@ -126,6 +132,19 @@
return (false);
}
+static void
+efi_shutdown_final(void *dummy __unused, int howto)
+{
+
+ /*
+ * On some systems, ACPI S5 is missing or does not function properly.
+ * When present, shutdown via EFI Runtime Services instead, unless
+ * disabled.
+ */
+ if ((howto & RB_POWEROFF) != 0 && efi_poweroff)
+ (void)efi_reset_system(EFI_RESET_SHUTDOWN);
+}
+
static int
efi_init(void)
{
@@ -214,6 +233,12 @@
}
#endif
+ /*
+ * We use SHUTDOWN_PRI_LAST - 1 to trigger after IPMI, but before ACPI.
+ */
+ EVENTHANDLER_REGISTER(shutdown_final, efi_shutdown_final, NULL,
+ SHUTDOWN_PRI_LAST - 1);
+
return (0);
}
@@ -411,16 +436,24 @@
}
int
-efi_reset_system(void)
+efi_reset_system(enum efi_reset type)
{
struct efirt_callinfo ec;
+ switch (type) {
+ case EFI_RESET_COLD:
+ case EFI_RESET_WARM:
+ case EFI_RESET_SHUTDOWN:
+ break;
+ default:
+ return (EINVAL);
+ }
if (efi_runtime == NULL)
return (ENXIO);
bzero(&ec, sizeof(ec));
ec.ec_name = "rt_reset";
ec.ec_argcnt = 4;
- ec.ec_arg1 = (uintptr_t)EFI_RESET_WARM;
+ ec.ec_arg1 = (uintptr_t)type;
ec.ec_arg2 = (uintptr_t)0;
ec.ec_arg3 = (uintptr_t)0;
ec.ec_arg4 = (uintptr_t)NULL;
Index: sys/dev/ipmi/ipmi.c
===================================================================
--- sys/dev/ipmi/ipmi.c
+++ sys/dev/ipmi/ipmi.c
@@ -938,14 +938,14 @@
} else if (!on)
(void)ipmi_set_watchdog(sc, 0);
/*
- * Power cycle the system off using IPMI. We use last - 1 since we don't
+ * Power cycle the system off using IPMI. We use last - 2 since we don't
* handle all the other kinds of reboots. We'll let others handle them.
* We only try to do this if the BMC supports the Chassis device.
*/
if (sc->ipmi_dev_support & IPMI_ADS_CHASSIS) {
device_printf(dev, "Establishing power cycle handler\n");
sc->ipmi_power_cycle_tag = EVENTHANDLER_REGISTER(shutdown_final,
- ipmi_power_cycle, sc, SHUTDOWN_PRI_LAST - 1);
+ ipmi_power_cycle, sc, SHUTDOWN_PRI_LAST - 2);
}
}
Index: sys/sys/efi.h
===================================================================
--- sys/sys/efi.h
+++ sys/sys/efi.h
@@ -42,8 +42,9 @@
{0xeb9d2d32,0x2d88,0x11d3,0x9a,0x16,{0x00,0x90,0x27,0x3f,0xc1,0x4d}}
enum efi_reset {
- EFI_RESET_COLD,
- EFI_RESET_WARM
+ EFI_RESET_COLD = 0,
+ EFI_RESET_WARM = 1,
+ EFI_RESET_SHUTDOWN = 2,
};
typedef uint16_t efi_char;
@@ -184,7 +185,7 @@
int efi_get_table(struct uuid *uuid, void **ptr);
int efi_get_time(struct efi_tm *tm);
int efi_get_time_capabilities(struct efi_tmcap *tmcap);
-int efi_reset_system(void);
+int efi_reset_system(enum efi_reset type);
int efi_set_time(struct efi_tm *tm);
int efi_var_get(uint16_t *name, struct uuid *vendor, uint32_t *attrib,
size_t *datasize, void *data);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Dec 21, 11:02 AM (17 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15540640
Default Alt Text
D18506.id51885.diff (4 KB)
Attached To
Mode
D18506: efirt: When present, attempt to use EFI runtime services to shutdown
Attached
Detach File
Event Timeline
Log In to Comment