Permalink
Browse files

Add support to enable firmware updates on supported systems using lib…

…smbios
  • Loading branch information...
1 parent e189f7a commit 3b08a1622e92c3a9c42f6773214dc3f41f13484b @superm1 superm1 committed with vathpela Feb 23, 2016
Showing with 116 additions and 2 deletions.
  1. +1 −1 linux/Makefile
  2. +36 −0 linux/fwupdate.c
  3. +1 −0 linux/include/fwup.h
  4. +78 −1 linux/libfwup.c
View
@@ -2,7 +2,7 @@ TOPDIR ?= $(shell pwd)/..
include $(TOPDIR)/Make.version
include $(TOPDIR)/Make.defaults
-LIB_LIBS= pthread
+LIB_LIBS= pthread smbios_c
BIN_LIBS= popt pthread
PKLIBS = efivar efiboot
CFLAGS ?= -g -O0
View
@@ -70,6 +70,7 @@ print_system_resources(void)
#define ACTION_LIST 0x02
#define ACTION_SUPPORTED 0x04
#define ACTION_INFO 0x08
+#define ACTION_ENABLE 0x10
int
main(int argc, char *argv[]) {
@@ -114,6 +115,12 @@ main(int argc, char *argv[]) {
.val = ACTION_INFO,
.descrip =
_("Show the information of firmware update status")},
+ {.longName = "enable",
+ .shortName = 'e',
+ .argInfo = POPT_ARG_VAL|POPT_ARGFLAG_OR,
+ .arg = &action,
+ .val = ACTION_ENABLE,
+ .descrip = _("Enable firmware update support on supported systems (will require a reboot)") },
{.longName = "quiet",
.shortName = 'q',
.argInfo = POPT_ARG_VAL,
@@ -183,6 +190,15 @@ main(int argc, char *argv[]) {
if (!quiet)
printf("%s", _("Firmware updates are supported on this machine.\n"));
return 0;
+ } else if (rc == 2) {
+ if (!quiet)
+ printf("%s", _("Firmware updates are supported on this machine, but currently disabled.\n"));
+ return 2;
+ }
+ else if (rc == 3) {
+ if (!quiet)
+ printf("%s", _("Firmware updates are supported on this machine, and will be enabled on the next reboot.\n"));
+ return 2;
}
} else if (action & ACTION_LIST) {
rc = print_system_resources();
@@ -224,6 +240,26 @@ main(int argc, char *argv[]) {
if (rc < 0)
errx(6, _("Could not display firmware update status"));
return 0;
+ } else if (action & ACTION_ENABLE) {
+ if (geteuid() != 0) {
+ if (!quiet)
+ printf("%s", _("To enable firmware updates, this tool must be launched as root.\n"));
+ return -1;
+ }
+ rc = enable_esrt();
+ if (rc < 1) {
+ if (!quiet)
+ printf("%s", _("Firmware updates can not be enabled on this machine from this tool.\n"));
+ return 1;
+ } else if (rc == 1) {
+ if (!quiet)
+ printf("%s", _("Firmware updates are already enabled.\n"));
+ return 1;
+ } else if (rc == 2 || rc == 3) {
+ if (!quiet)
+ printf("%s", _("Firmware updates will be enabled after the system is rebooted.\n"));
+ return 0;
+ }
}
return 0;
View
@@ -17,6 +17,7 @@
#include <time.h>
extern int fwup_supported(void);
+extern int enable_esrt(void);
#define FWUP_RESOURCE_TYPE_UNKNOWN 0
#define FWUP_RESOURCE_TYPE_SYSTEM_FIRMWARE 1
View
@@ -29,6 +29,10 @@
#include "ucs2.h"
#include "fwup-efi.h"
+#include </usr/include/smbios_c/token.h>
+#define DELL_CAPSULE_FIRMWARE_UPDATES_ENABLED 0x0461
+#define DELL_CAPSULE_FIRMWARE_UPDATES_DISABLED 0x0462
+
static char *arch_names_32[] = {
#if defined(__x86_64__) || defined(__i386__) || defined(__i686__)
"ia32",
@@ -78,6 +82,73 @@ efidp_end_entire(efidp_header *dp)
return 1;
}
+/*
+ esrt_disabled
+ tests if ESRT is disabled (but can be enabled)
+ return codes:
+ -1 : the tokens were not found. system is unsupported
+ -2 : libsmbios failure, this scenario shouldn't be reached
+ 2 : ESRT is currently disabled and can be enabled.
+ 3 : tokens were found, will be enabled next boot
+
+ */
+int
+esrt_disabled(void)
+{
+ if (!token_is_bool(DELL_CAPSULE_FIRMWARE_UPDATES_DISABLED))
+ return -1;
+ if (!token_is_active(DELL_CAPSULE_FIRMWARE_UPDATES_DISABLED))
+ {
+ if (token_is_active(DELL_CAPSULE_FIRMWARE_UPDATES_ENABLED))
+ return 3;
+ return -2;
+ }
+ return 2;
+}
+
+/*
+ enable_esrt
+ attempts to enable ESRT
+ return codes:
+ <= 0 : failure
+ 1 : already enabled
+ 2 : success
+ 3 : tokens were found, will be enabled next boot
+
+ */
+int
+enable_esrt(void)
+{
+ int rc;
+ rc = fwup_supported();
+ /* can't enable or already enabled */
+ if (rc != 2)
+ return rc;
+ /* disabled in BIOS, but supported to be enabled via tool */
+ rc = token_is_bool(DELL_CAPSULE_FIRMWARE_UPDATES_ENABLED);
+ if (!rc)
+ return -1;
+ rc = token_is_active(DELL_CAPSULE_FIRMWARE_UPDATES_ENABLED);
+ if (rc)
+ return -2;
+ token_activate(DELL_CAPSULE_FIRMWARE_UPDATES_ENABLED);
+ rc = token_is_active(DELL_CAPSULE_FIRMWARE_UPDATES_ENABLED);
+ if (!rc)
+ return -3;
+ return 2;
+}
+
+/*
+ fwup_supported
+ tests if firmware updating supported
+ return codes:
+ <0 : error
+ 0 : unsupported
+ 1 : supported
+ 2 : ESRT is currently disabled but can be enabled
+ 3 : ESRT is currently disabled but will be enabled on next boot
+
+ */
int
fwup_supported(void)
{
@@ -86,7 +157,13 @@ fwup_supported(void)
rc = stat(get_esrt_dir(1), &buf);
if (rc < 0)
- return 0;
+ {
+ /* check if we have the ability to turn on ESRT */
+ rc = esrt_disabled();
+ if (rc < 0)
+ return 0;
+ return rc;
+ }
if (buf.st_nlink < 3)
return 0;
return 1;

0 comments on commit 3b08a16

Please sign in to comment.