[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