Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144475885
D18506.id51846.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D18506.id51846.diff
View Options
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>
@@ -95,6 +97,7 @@
static int efi_enter(void);
static void efi_leave(void);
+static int _efi_reset_system(enum efi_reset);
static int
efi_status_to_errno(efi_status status)
@@ -106,6 +109,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 shutdown in preference to ACPI");
static bool
efi_is_in_map(struct efi_md *map, int ndesc, int descsz, vm_offset_t addr)
@@ -126,6 +133,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 +234,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);
}
@@ -410,8 +436,8 @@
return (error);
}
-int
-efi_reset_system(void)
+static int
+_efi_reset_system(enum efi_reset type)
{
struct efirt_callinfo ec;
@@ -420,7 +446,7 @@
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;
@@ -428,6 +454,13 @@
return (efi_call(&ec));
}
+int
+efi_reset_system(void)
+{
+
+ return (_efi_reset_system(EFI_RESET_WARM));
+}
+
static int
efi_set_time_locked(struct efi_tm *tm)
{
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
@@ -43,7 +43,8 @@
enum efi_reset {
EFI_RESET_COLD,
- EFI_RESET_WARM
+ EFI_RESET_WARM,
+ EFI_RESET_SHUTDOWN,
};
typedef uint16_t efi_char;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 9, 3:36 PM (21 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28595015
Default Alt Text
D18506.id51846.diff (3 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