diff --git a/sys/kern/subr_firmware.c b/sys/kern/subr_firmware.c --- a/sys/kern/subr_firmware.c +++ b/sys/kern/subr_firmware.c @@ -442,6 +442,57 @@ mtx_unlock(&firmware_mtx); } +/* + * Find all the firmware that was loaded in the boot loader vis load -t firmware + * foo. There is only one firmware per file, it's the whole file, and there's no + * meaningful version passed in, so pass 0 for that. If version is needed by the + * consumer (and not just arbitrarily defined), the .ko version must be used + * instead. + */ +static void +firmware_raw_files(void) +{ + caddr_t file; + char *fullname, *name; + const char *type; + const void *addr; + size_t size; + unsigned int version = 0; + + file = 0; + for (;;) { + file = preload_search_next_name(file); + if (file == 0) + break; + type = (const char *)preload_search_info(file, MODINFO_TYPE); + if (type == NULL || strcmp(type, "firmware") != 0) + continue; + fullname = strdup(preload_search_info(file, MODINFO_NAME), + M_FIRMWARE); + addr = preload_fetch_addr(file); + size = preload_fetch_size(file); + /* + * version hard wired to 0 and the firmware name matches what's + * loaded with the .bin stripped off the end (if any). The args + * could be used to pass in parameters to override this, but not + * currently. We strip the path and look only at the filename + * part. + */ + name = strrchr(fullname, '/'); + if (name == NULL) + name = fullname; + else + name++; + if (strlen(name) > 4) { + char *t = name + strlen(name) - 4; + if (strcmp(t, ".bin") == 0) + *t = '\0'; + } + firmware_register(name, addr, size, version, NULL); + free(name, M_FIRMWARE); + } +} + /* * Module glue. */ @@ -460,6 +511,7 @@ /* NB: use our own loop routine that sets up context */ (void) taskqueue_start_threads(&firmware_tq, 1, PWAIT, "firmware taskq"); + firmware_raw_files(); if (rootvnode != NULL) { /* * Root is already mounted so we won't get an event;