Lines Matching +full:firmware +full:- +full:name
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2005-2008, Sam Leffler <sam@errno.com>
33 #include <sys/firmware.h>
53 * Loadable firmware support. See sys/sys/firmware.h and firmware(9)
56 * 'struct firmware' is the user-visible part of the firmware table.
58 * which embeds the public firmware structure.
62 * fw.name != NULL when an image is registered; file != NULL for
66 * firmware_register --> fw.name = image_name
67 * (autoloaded image) --> file = module reference
68 * firmware_unregister --> fw.name = NULL
69 * (unloadentry complete) --> file = NULL
76 * One image (typically, one with the same name as the module to let
93 #define FW_BINARY 0x080 /* Firmware directly loaded, file == NULL */
111 struct firmware fw; /* externally visible information */
115 * PRIV_FW returns the pointer to the container of struct firmware *x.
119 ((intptr_t)(x) - offsetof(struct priv_fw, fw)) )
122 * Global firmware image registry.
127 * Firmware module operations are handled in a separate task as they
135 * This mutex protects accesses to the firmware table.
138 MTX_SYSINIT(firmware, &firmware_mtx, "firmware table", MTX_DEF);
140 static MALLOC_DEFINE(M_FIRMWARE, "firmware", "device firmware images");
145 "Max size permitted for a firmware file.");
148 * Helper function to lookup a name.
155 lookup(const char *name)
162 if (fp->fw.name != NULL && strcasecmp(name, fp->fw.name) == 0)
166 * If the name looks like an absolute path, also try to match
167 * the last part of the string to the requested firmware if it
169 * /boot/firmware/abc/bca2233_fw.bin and match it against
172 if (*fp->fw.name == '/' && strlen(fp->fw.name) > strlen(name)) {
173 const char *p = fp->fw.name + strlen(fp->fw.name) - strlen(name);
174 if (p[-1] == '/' && strcasecmp(name, p) == 0)
182 * Register a firmware image with the specified name. The
183 * image name must not already be registered. If this is a
187 const struct firmware *
189 unsigned int version, const struct firmware *parent)
192 char *name;
205 name = strdup(imagename, M_FIRMWARE);
211 free(name, M_FIRMWARE);
215 frp->fw.name = name;
216 frp->fw.data = data;
217 frp->fw.datasize = datasize;
218 frp->fw.version = version;
220 frp->parent = PRIV_FW(parent);
224 printf("firmware: '%s' version %u: %zu bytes loaded at %p\n",
226 return (&frp->fw);
230 * Unregister/remove a firmware image. If there are outstanding
247 * firmware images.
250 } else if (fp->refcnt != 0) { /* cannot unregister */
254 free(__DECONST(char *, fp->fw.name), M_FIRMWARE);
267 static const char *fw_path = "/boot/firmware/";
274 struct ucred *cred = td ? td->td_ucred : NULL;
280 const struct firmware *fw;
295 printf("Trying to load binary firmware from %s\n", fn);
303 if (nd.ni_vp->v_type != VREG)
313 printf("Firmware %s is too big: %lld bytes, %ld bytes max.\n",
330 fp->flags |= FW_BINARY;
332 printf("%s: Loaded binary firmware using %s\n", imagename, fn);
342 printf("%s: could not load binary firmware %s either\n", imagename, fn);
354 error = linker_reference_module(fwli->imagename, NULL, &result);
356 if (bootverbose || (fwli->flags & FIRMWARE_GET_NOWARN) == 0)
357 printf("%s: could not load firmware image, error %d\n",
358 fwli->imagename, error);
359 try_binary_file(fwli->imagename, fwli->flags);
365 fp = lookup(fwli->imagename);
366 if (fp == NULL || fp->file != NULL) {
369 printf("%s: firmware image loaded, "
370 "but did not register\n", fwli->imagename);
371 (void) linker_release_module(fwli->imagename, NULL, NULL);
375 fp->file = result; /* record the module identity */
382 * Lookup and potentially load the specified firmware image.
383 * If the firmware is not found in the registry, try to load a kernel
384 * module named as the image name.
385 * If the firmware is located, a reference is returned. The caller must
388 const struct firmware *
404 securelevel_gt(td->td_ucred, 0) != 0) {
407 "load firmware image %s\n", __func__, imagename);
433 if (fp->refcnt == 0 && fp->parent != NULL)
434 fp->parent->refcnt++;
435 fp->refcnt++;
437 return &fp->fw;
440 const struct firmware *
448 * Release a reference to a firmware image returned by firmware_get.
452 * If this is the last reference to the firmware image, and this is an
457 firmware_put(const struct firmware *p, int flags)
462 fp->refcnt--;
463 if (fp->refcnt == 0) {
464 if (fp->parent != NULL)
465 fp->parent->refcnt--;
467 fp->flags |= FW_UNLOAD;
468 if (fp->file)
506 * Images can be cross-linked so we may need to make multiple passes,
518 if (((fp->flags & FW_BINARY) == 0 && fp->file == NULL) ||
519 fp->refcnt != 0 || (fp->flags & FW_UNLOAD) == 0)
523 * If we directly loaded the firmware, then we just need to
528 if ((fp->flags & FW_BINARY) != 0) {
530 free(__DECONST(char *, fp->fw.data), M_FIRMWARE);
531 free(__DECONST(char *, fp->fw.name), M_FIRMWARE);
543 fp->flags &= ~FW_UNLOAD; /* do not try again */
550 (void)linker_release_module(NULL, NULL, fp->file);
563 * Find all the binary firmware that was loaded in the boot loader via load -t
564 * firmware foo. There is only one firmware per file, it's the whole file, and
573 char *name;
578 const struct firmware *fw;
587 if (type == NULL || strcmp(type, "firmware") != 0)
589 name = preload_search_info(file, MODINFO_NAME);
592 fw = firmware_register(name, addr, size, version, NULL);
594 fp->refcnt++; /* Hold an extra reference so we never unload */
615 "firmware taskq");
630 fp->flags |= FW_UNLOAD;
636 if (fp->fw.name != NULL) {
638 __func__, fp->fw.name, fp->refcnt);
654 "firmware",
658 DECLARE_MODULE(firmware, firmware_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
659 MODULE_VERSION(firmware, 1);