70 lines
1.5 KiB
C
70 lines
1.5 KiB
C
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
|
/* Copyright 2021 Stewart Smith */
|
|
|
|
#define pr_fmt(fmt) "HWPROBE: " fmt
|
|
#include <skiboot.h>
|
|
#include <string.h>
|
|
|
|
static bool hwprobe_deps_satisfied(const struct hwprobe *hwp)
|
|
{
|
|
struct hwprobe *hwprobe;
|
|
const char **dep;
|
|
unsigned int i;
|
|
|
|
dep = hwp->deps;
|
|
if (dep == NULL)
|
|
return true;
|
|
|
|
|
|
prlog(PR_TRACE, "Checking deps for %s\n", hwp->name);
|
|
|
|
while (*dep != NULL) {
|
|
prlog(PR_TRACE, "Checking %s dep %s\n", hwp->name, *dep);
|
|
hwprobe = &__hwprobes_start;
|
|
for (i = 0; &hwprobe[i] < &__hwprobes_end; i++) {
|
|
if(strcmp(hwprobe[i].name, *dep) == 0 &&
|
|
!hwprobe[i].probed)
|
|
return false;
|
|
}
|
|
dep++;
|
|
}
|
|
|
|
prlog(PR_TRACE, "deps for %s are satisfied!\n", hwp->name);
|
|
return true;
|
|
|
|
}
|
|
|
|
void probe_hardware(void)
|
|
{
|
|
struct hwprobe *hwprobe;
|
|
unsigned int i;
|
|
bool work_todo = true;
|
|
bool did_something = true;
|
|
|
|
while (work_todo) {
|
|
work_todo = false;
|
|
did_something = false;
|
|
hwprobe = &__hwprobes_start;
|
|
prlog(PR_DEBUG, "Begin loop\n");
|
|
for (i = 0; &hwprobe[i] < &__hwprobes_end; i++) {
|
|
if (hwprobe[i].probed)
|
|
continue;
|
|
if (hwprobe_deps_satisfied(&hwprobe[i])) {
|
|
prlog(PR_DEBUG, "Probing %s...\n", hwprobe[i].name);
|
|
if (hwprobe[i].probe)
|
|
hwprobe[i].probe();
|
|
did_something = true;
|
|
hwprobe[i].probed = true;
|
|
} else {
|
|
prlog(PR_DEBUG, "Dependencies for %s not yet satisfied, skipping\n",
|
|
hwprobe[i].name);
|
|
work_todo = true;
|
|
}
|
|
}
|
|
|
|
if (work_todo && !did_something) {
|
|
prlog(PR_ERR, "Cannot satisfy dependencies! Bailing out\n");
|
|
break;
|
|
}
|
|
}
|
|
}
|