[Glibc-bsd-commits] r5413 - in trunk/kfreebsd-10/debian: . patches
rmh at alioth.debian.org
rmh at alioth.debian.org
Mon Feb 3 23:51:19 UTC 2014
Author: rmh
Date: 2014-02-03 23:51:19 +0000 (Mon, 03 Feb 2014)
New Revision: 5413
Added:
trunk/kfreebsd-10/debian/patches/firmware_load.diff
Modified:
trunk/kfreebsd-10/debian/changelog
trunk/kfreebsd-10/debian/patches/series
Log:
firmware_load.diff: Loads firmware blobs from /lib/firmware/. Currently supports radeonkmsfw, ral, iwi, wpi, wpi, ipw, iwn and rsu. (Closes: #642468)
Modified: trunk/kfreebsd-10/debian/changelog
===================================================================
--- trunk/kfreebsd-10/debian/changelog 2014-02-03 22:35:03 UTC (rev 5412)
+++ trunk/kfreebsd-10/debian/changelog 2014-02-03 23:51:19 UTC (rev 5413)
@@ -3,6 +3,9 @@
* Accept O_CLOEXEC in shm_open().
* radeonkms: Disable R600+ drivers when no firmware blob is available.
(Closes: #732692)
+ * firmware_load.diff: Loads firmware blobs from /lib/firmware/.
+ Currently supports radeonkmsfw, ral, iwi, wpi, wpi, ipw, iwn and
+ rsu. (Closes: #642468)
-- Robert Millan <rmh at debian.org> Fri, 24 Jan 2014 22:32:32 +0100
Added: trunk/kfreebsd-10/debian/patches/firmware_load.diff
===================================================================
--- trunk/kfreebsd-10/debian/patches/firmware_load.diff (rev 0)
+++ trunk/kfreebsd-10/debian/patches/firmware_load.diff 2014-02-03 23:51:19 UTC (rev 5413)
@@ -0,0 +1,177 @@
+
+Loads firmware blobs from /lib/firmware/
+
+Currently only radeonkmsfw is supported.
+
+--- a/sys/kern/subr_firmware.c
++++ b/sys/kern/subr_firmware.c
+@@ -45,6 +45,12 @@
+
+ #include <sys/filedesc.h>
+ #include <sys/vnode.h>
++#include <sys/fcntl.h>
++#define lookup(a) namei_lookup(a)
++#include <sys/namei.h>
++#undef lookup
++
++MALLOC_DEFINE(M_FIRMWARE, "firmware", "firmware loader");
+
+ /*
+ * Loadable firmware support. See sys/sys/firmware.h and firmware(9)
+@@ -137,6 +143,124 @@
+ static struct mtx firmware_mtx;
+ MTX_SYSINIT(firmware, &firmware_mtx, "firmware table", MTX_DEF);
+
++MALLOC_DECLARE(M_FIRMWARE);
++
++static const struct
++{
++ char *file;
++ char *name;
++} firmware_map[] = {
++
++ /*
++ * Second column is the argument to firmware_get() used by the
++ * driver. If there are no firmware_get() calls this means it
++ * needs to be ported to firmware(9) framework first.
++ *
++ * Note that the first column may refer to a versioned file
++ * name, but the second one is NOT versioned. The versioned
++ * references are supposed to match with whatever this version
++ * of the kernel expects (check the makefiles for *fw modules
++ * in sys/modules/ for hints).
++ */
++
++ /* ral */
++ { "/lib/firmware/rt2561.bin", "rt2561fw" },
++ { "/lib/firmware/rt2661.bin", "rt2661fw" },
++ { "/lib/firmware/rt2561s.bin", "rt2561sfw" },
++
++ /* iwi */
++ { "/lib/firmware/ipw2200-bss.fw", "iwi_bss" },
++ { "/lib/firmware/ipw2200-ibss.fw", "iwi_ibss" },
++ { "/lib/firmware/ipw2200-sniffer.fw", "iwi_monitor" },
++
++ /* wpi */
++ { "/lib/firmware/iwlwifi-3945-2.ucode", "wpifw" },
++
++ /* ipw */
++ { "/lib/firmware/ipw2100-1.3.fw", "ipw_bss" },
++ { "/lib/firmware/ipw2100-1.3-i.fw", "ipw_ibss" },
++ { "/lib/firmware/ipw2100-1.3-p.fw", "ipw_monitor" },
++
++ /* iwn */
++ { "/lib/firmware/iwlwifi-105-6.ucode", "iwn105fw" },
++ { "/lib/firmware/iwlwifi-135-6.ucode", "iwn135fw" },
++ { "/lib/firmware/iwlwifi-1000-5.ucode", "iwn1000fw" },
++ { "/lib/firmware/iwlwifi-2000-6.ucode", "iwn2000fw" },
++ { "/lib/firmware/iwlwifi-2030-6.ucode", "iwn2030fw" },
++ { "/lib/firmware/iwlwifi-4965-2.ucode", "iwn4965fw" },
++ { "/lib/firmware/iwlwifi-5000-5.ucode", "iwn5000fw" },
++ { "/lib/firmware/iwlwifi-5150-2.ucode", "iwn5150fw" },
++ { "/lib/firmware/iwlwifi-6000-4.ucode", "iwn6000fw" },
++ { "/lib/firmware/iwlwifi-6050-5.ucode", "iwn6050fw" },
++ { "/lib/firmware/iwlwifi-6000g2a-6.ucode", "iwn6000g2afw" },
++ { "/lib/firmware/iwlwifi-6000g2b-6.ucode", "iwn6000g2bfw" },
++
++ /* rsu */
++ { "/lib/firmware/rtlwifi/rtl8712u.bin", "rsu-rtl8712fw" },
++};
++
++static const struct firmware *
++firmware_load(const char *path, const char *imagename)
++{
++ struct thread *td = curthread; /* XXX */
++ struct ucred *cred = td ? td->td_ucred : NULL;
++ struct nameidata nd;
++ struct vattr vattr;
++ u_char *fwdata = NULL;
++ u_char *cp;
++ int error, flags;
++ ssize_t reclen;
++ const struct firmware *result = NULL;
++
++ NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, path, td);
++ flags = FREAD;
++ error = vn_open(&nd, &flags, 0, NULL);
++ if (error)
++ goto bad;
++ NDFREE(&nd, NDF_ONLY_PNBUF);
++ if (nd.ni_vp->v_type != VREG)
++ goto bad;
++ cp = NULL;
++ error = VOP_GETATTR(nd.ni_vp, &vattr, cred);
++ if (error)
++ goto bad;
++ /*
++ * XXX: we need to limit this number to some reasonable value
++ */
++ if (vattr.va_size > 100 * 1024) {
++ printf("firmware image file too large %ld\n", (long)vattr.va_size);
++ goto bad;
++ }
++ fwdata = malloc(vattr.va_size, M_FIRMWARE, M_WAITOK);
++ if (fwdata == NULL)
++ goto bad;
++ error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)fwdata, vattr.va_size, 0,
++ UIO_SYSSPACE, IO_NODELOCKED, cred, NOCRED, &reclen, td);
++ if (error)
++ goto bad;
++ VOP_UNLOCK(nd.ni_vp, 0);
++ vn_close(nd.ni_vp, FREAD, cred, td);
++ nd.ni_vp = NULL;
++ if (reclen != 0) {
++ printf("can't read %zd\n", reclen);
++ goto bad;
++ }
++ result = firmware_register(imagename, fwdata, vattr.va_size, 0, NULL);
++bad:
++ if (result == NULL) {
++ printf("unable to load %s", path);
++ }
++
++ if (fwdata && !result)
++ free(fwdata, M_FIRMWARE);
++ if (nd.ni_vp != NULL) {
++ VOP_UNLOCK(nd.ni_vp, 0);
++ vn_close(nd.ni_vp, FREAD, cred, td);
++ }
++
++ return (result);
++}
++
+ /*
+ * Helper function to lookup a name.
+ * As a side effect, it sets the pointer to a free slot, if any.
+@@ -307,6 +431,31 @@
+ struct thread *td;
+ struct priv_fw *fp;
+
++ /*
++ * Must call firmware_load *before* entering the mutex.
++ */
++ if (!strncmp (imagename, "radeonkmsfw_", sizeof("radeonkmsfw_") - 1)) {
++ const char *basename = imagename + sizeof("radeonkmsfw_") - 1;
++ u_char *pathbuf;
++ ssize_t reclen;
++ reclen = sizeof("/lib/firmware/radeon/") - 1
++ + strlen(basename)
++ + sizeof(".bin");
++ pathbuf = malloc(reclen, M_TEMP, M_WAITOK);
++ snprintf(pathbuf, reclen, "/lib/firmware/radeon/%s.bin", basename);
++
++ firmware_load(pathbuf, imagename);
++
++ free(pathbuf, M_TEMP);
++ } else {
++ int i;
++ for (i = 0; i < sizeof(firmware_map)/sizeof(firmware_map[0]); i++)
++ if (!strcmp (firmware_map[i].name, imagename)) {
++ firmware_load(firmware_map[i].file, imagename);
++ break;
++ }
++ }
++
+ mtx_lock(&firmware_mtx);
+ fp = lookup(imagename, NULL);
+ if (fp != NULL)
Modified: trunk/kfreebsd-10/debian/patches/series
===================================================================
--- trunk/kfreebsd-10/debian/patches/series 2014-02-03 22:35:03 UTC (rev 5412)
+++ trunk/kfreebsd-10/debian/patches/series 2014-02-03 23:51:19 UTC (rev 5413)
@@ -18,6 +18,7 @@
109_linprocfs_non_x86.diff
# Patches that are likely to be Debian-specific
+firmware_load.diff
902_version.diff
904_dev_full.diff
906_grow_sysv_ipc_limits.diff
More information about the Glibc-bsd-commits
mailing list