Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108323291
D27413.id82883.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D27413.id82883.diff
View Options
Index: share/man/man9/firmware.9
===================================================================
--- share/man/man9/firmware.9
+++ share/man/man9/firmware.9
@@ -23,13 +23,14 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 14, 2019
+.Dd January 26, 2021
.Dt FIRMWARE 9
.Os
.Sh NAME
.Nm firmware_register ,
.Nm firmware_unregister ,
.Nm firmware_get ,
+.Nm firmware_get_flags ,
.Nm firmware_put
.Nd firmware image loading and management
.Sh SYNOPSIS
@@ -57,6 +58,8 @@
.Fn firmware_unregister "const char *imagename"
.Ft "const struct firmware *"
.Fn firmware_get "const char *imagename"
+.Ft "const struct firmware *"
+.Fn firmware_get_flags "const char *imagename" "uint32_t flags"
.Ft void
.Fn firmware_put "const struct firmware *fp" "int flags"
.Sh DESCRIPTION
@@ -97,7 +100,13 @@
.Fn firmware_get
with the
.Nm imagename
-they want as an argument.
+they want as an argument, or by calling
+.Fn firmware_get_flags
+with the
+.Nm imagename
+and
+.Nm flags
+they want as an arguments.
If a matching image is not already registered,
the firmware subsystem will try to load it using the
mechanisms specified below (typically, a kernel module
@@ -134,11 +143,22 @@
it does not unregister the image and returns EBUSY.
.Pp
.Fn firmware_get
-returns the requested firmware image.
+and
+.Fn firmware_get_flags
+return the requested firmware image.
+The
+.Fa flags
+argument may be set to
+.Dv FIRMWARE_GET_NOWARN
+to indicate that errors on firmware load or registration should
+only be logged in case of
+.Nm booverbose .
If the image is not yet registered with the system,
-the function tries to load it.
+the functions try to load it.
This involves the linker subsystem and disk access, so
.Fn firmware_get
+or
+.Fn firmware_get_flags
must not be called with any locks (except for
.Va Giant ) .
Note also that if the firmware image is loaded from a filesystem
@@ -149,9 +169,11 @@
.Pp
On success,
.Fn firmware_get
-returns a pointer to the image description and increases the reference count
+and
+.Fn firmware_get_flags
+return a pointer to the image description and increase the reference count
for this image.
-On failure, the function returns NULL.
+On failure, the functions return NULL.
.Pp
.Fn firmware_put
drops a reference to a firmware image.
@@ -183,10 +205,12 @@
.Pp
When
.Fn firmware_get
+or
+.Fn firmware_get_flags
does not find the requested image, it tries to load it using
one of the available loading mechanisms.
At the moment, there is only one, namely
-.Nm Loadable kernel modules :
+.Nm Loadable kernel modules .
.Pp
A firmware image named
.Nm foo
@@ -203,6 +227,8 @@
Note that in case a module contains multiple images,
the caller should first request a
.Fn firmware_get
+or
+.Fn firmware_get_flags
for the first image contained in the module, followed by requests
for the other images.
.Sh BUILDING FIRMWARE LOADABLE MODULES
Index: sys/kern/subr_firmware.c
===================================================================
--- sys/kern/subr_firmware.c
+++ sys/kern/subr_firmware.c
@@ -238,36 +238,42 @@
return (err);
}
+struct fw_loadimage {
+ const char *imagename;
+ uint32_t flags;
+};
+
static void
-loadimage(void *arg, int npending)
+loadimage(void *arg, int npending __unused)
{
- char *imagename = arg;
+ struct fw_loadimage *fwli = arg;
struct priv_fw *fp;
linker_file_t result;
int error;
- error = linker_reference_module(imagename, NULL, &result);
+ error = linker_reference_module(fwli->imagename, NULL, &result);
if (error != 0) {
- printf("%s: could not load firmware image, error %d\n",
- imagename, error);
+ if (bootverbose || (fwli->flags & FIRMWARE_GET_NOWARN) == 0)
+ printf("%s: could not load firmware image, error %d\n",
+ fwli->imagename, error);
mtx_lock(&firmware_mtx);
goto done;
}
mtx_lock(&firmware_mtx);
- fp = lookup(imagename);
+ fp = lookup(fwli->imagename);
if (fp == NULL || fp->file != NULL) {
mtx_unlock(&firmware_mtx);
if (fp == NULL)
printf("%s: firmware image loaded, "
- "but did not register\n", imagename);
- (void) linker_release_module(imagename, NULL, NULL);
+ "but did not register\n", fwli->imagename);
+ (void) linker_release_module(fwli->imagename, NULL, NULL);
mtx_lock(&firmware_mtx);
goto done;
}
fp->file = result; /* record the module identity */
done:
- wakeup_one(imagename);
+ wakeup_one(arg);
mtx_unlock(&firmware_mtx);
}
@@ -279,7 +285,7 @@
* release this reference for the image to be eligible for removal/unload.
*/
const struct firmware *
-firmware_get(const char *imagename)
+firmware_get_flags(const char *imagename, uint32_t flags)
{
struct task fwload_task;
struct thread *td;
@@ -306,11 +312,15 @@
* Also we must not hold any mtx's over this call which is problematic.
*/
if (!cold) {
- TASK_INIT(&fwload_task, 0, loadimage, __DECONST(void *,
- imagename));
+ struct fw_loadimage fwli;
+
+ fwli.imagename = imagename;
+ fwli.flags = flags;
+ PHOLD(curproc);
+ TASK_INIT(&fwload_task, 0, loadimage, (void *)&fwli);
taskqueue_enqueue(firmware_tq, &fwload_task);
- msleep(__DECONST(void *, imagename), &firmware_mtx, 0,
- "fwload", 0);
+ msleep((void *)&fwli, &firmware_mtx, 0, "fwload", 0);
+ PRELE(curproc);
}
/*
* After attempting to load the module, see if the image is registered.
@@ -328,6 +338,13 @@
return &fp->fw;
}
+const struct firmware *
+firmware_get(const char *imagename)
+{
+
+ return (firmware_get_flags(imagename, 0));
+}
+
/*
* Release a reference to a firmware image returned by firmware_get.
* The caller may specify, with the FIRMWARE_UNLOAD flag, its desire
Index: sys/sys/firmware.h
===================================================================
--- sys/sys/firmware.h
+++ sys/sys/firmware.h
@@ -60,7 +60,12 @@
const struct firmware *firmware_register(const char *,
const void *, size_t, unsigned int, const struct firmware *);
int firmware_unregister(const char *);
+
+#define FIRMWARE_GET_NOWARN 0x0001 /* Do not warn if firmware not found. */
+const struct firmware *firmware_get_flags(const char *, uint32_t flags);
const struct firmware *firmware_get(const char *);
+
#define FIRMWARE_UNLOAD 0x0001 /* unload if unreferenced */
void firmware_put(const struct firmware *, int);
+
#endif /* _SYS_FIRMWARE_H_ */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 24, 9:00 PM (17 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16103358
Default Alt Text
D27413.id82883.diff (6 KB)
Attached To
Mode
D27413: firmware(9): extend firmware_get () by a "no warn" flag.
Attached
Detach File
Event Timeline
Log In to Comment