summaryrefslogtreecommitdiffstats
path: root/discover/platform-powerpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'discover/platform-powerpc.c')
-rw-r--r--discover/platform-powerpc.c78
1 files changed, 48 insertions, 30 deletions
diff --git a/discover/platform-powerpc.c b/discover/platform-powerpc.c
index 6ae28f4..5f6772f 100644
--- a/discover/platform-powerpc.c
+++ b/discover/platform-powerpc.c
@@ -30,7 +30,12 @@ struct param {
};
struct platform_powerpc {
- struct list params;
+ struct list params;
+ int (*get_ipmi_bootdev)(
+ struct platform_powerpc *platform,
+ uint8_t *bootdev, bool *persistent);
+ int (*clear_ipmi_bootdev)(
+ struct platform_powerpc *platform);
};
static const char *known_params[] = {
@@ -570,32 +575,17 @@ static int update_config(struct platform_powerpc *platform,
return write_nvram(platform);
}
-static void set_exclusive_devtype(struct config *config,
- enum device_type devtype)
+static void set_ipmi_bootdev(struct config *config, enum ipmi_bootdev bootdev,
+ bool persistent)
{
- config->n_boot_priorities = 2;
- config->boot_priorities = talloc_realloc(config,
- config->boot_priorities, struct boot_priority,
- config->n_boot_priorities);
- config->boot_priorities[0].type = devtype;
- config->boot_priorities[0].priority = 0;
- config->boot_priorities[1].type = DEVICE_TYPE_ANY;
- config->boot_priorities[1].priority = -1;
-}
+ config->ipmi_bootdev = bootdev;
+ config->ipmi_bootdev_persistent = persistent;
-static void set_ipmi_bootdev(struct config *config, enum ipmi_bootdev bootdev)
-{
switch (bootdev) {
case IPMI_BOOTDEV_NONE:
- break;
case IPMI_BOOTDEV_DISK:
- set_exclusive_devtype(config, DEVICE_TYPE_DISK);
- break;
case IPMI_BOOTDEV_NETWORK:
- set_exclusive_devtype(config, DEVICE_TYPE_NETWORK);
- break;
case IPMI_BOOTDEV_CDROM:
- set_exclusive_devtype(config, DEVICE_TYPE_OPTICAL);
break;
case IPMI_BOOTDEV_SETUP:
config->autoboot_enabled = false;
@@ -684,7 +674,17 @@ static int write_bootdev_sysparam(const char *name, uint8_t val)
return rc;
}
-static void parse_opal_sysparams(struct config *config)
+static int clear_ipmi_bootdev_sysparams(
+ struct platform_powerpc *platform __attribute__((unused)))
+{
+ /* invalidate next-boot-device setting */
+ write_bootdev_sysparam("next-boot-device", 0xff);
+ return 0;
+}
+
+static int get_ipmi_bootdev_sysparams(
+ struct platform_powerpc *platform __attribute__((unused)),
+ uint8_t *bootdev, bool *persistent)
{
uint8_t next_bootdev, default_bootdev;
bool next_valid, default_valid;
@@ -698,12 +698,11 @@ static void parse_opal_sysparams(struct config *config)
/* nothing valid? no need to change the config */
if (!next_valid && !default_valid)
- return;
-
- if (!next_valid)
- next_bootdev = default_bootdev;
+ return -1;
- set_ipmi_bootdev(config, next_bootdev);
+ *persistent = !next_valid;
+ *bootdev = next_valid ? next_bootdev : default_bootdev;
+ return 0;
}
static int load_config(struct platform *p, struct config *config)
@@ -717,7 +716,15 @@ static int load_config(struct platform *p, struct config *config)
populate_config(platform, config);
- parse_opal_sysparams(config);
+ if (platform->get_ipmi_bootdev) {
+ bool bootdev_persistent;
+ uint8_t bootdev;
+ rc = platform->get_ipmi_bootdev(platform, &bootdev,
+ &bootdev_persistent);
+ if (!rc && ipmi_bootdev_is_valid(bootdev)) {
+ set_ipmi_bootdev(config, bootdev, bootdev_persistent);
+ }
+ }
return 0;
}
@@ -737,10 +744,12 @@ static int save_config(struct platform *p, struct config *config)
return rc;
}
-static void finalise_config(struct platform *platform __attribute__((unused)))
+static void finalise_config(struct platform *p, const struct config *config)
{
- /* invalidate next-boot-device setting */
- write_bootdev_sysparam("next-boot-device", 0xff);
+ struct platform_powerpc *platform = to_platform_powerpc(p);
+
+ if (config->ipmi_bootdev_persistent && platform->clear_ipmi_bootdev)
+ platform->clear_ipmi_bootdev(platform);
}
static int get_sysinfo(struct platform *p, struct system_info *sysinfo)
@@ -782,6 +791,15 @@ static bool probe(struct platform *p, void *ctx)
list_init(&platform->params);
p->platform_data = platform;
+
+ if (!stat(sysparams_dir, &statbuf)) {
+ pb_debug("platform: using sysparams for IPMI paramters\n");
+ platform->get_ipmi_bootdev = get_ipmi_bootdev_sysparams;
+ platform->clear_ipmi_bootdev = clear_ipmi_bootdev_sysparams;
+
+ } else {
+ pb_log("platform: no IPMI parameter support\n");
+ }
return true;
}
OpenPOWER on IntegriCloud