summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/systemd/systemd
diff options
context:
space:
mode:
authorJonathan Liu <net147@gmail.com>2015-03-19 15:38:32 +1100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-03-23 10:33:06 +0000
commit814252efd028ec99a15303d9a551e950e49a6726 (patch)
tree02e2e7966f60d10b0834fceada27a543f3092c66 /meta/recipes-core/systemd/systemd
parentbbc139617637392a9b0fb2e9332a42ad64a4a556 (diff)
downloadpoky-814252efd028ec99a15303d9a551e950e49a6726.tar.gz
systemd: restore userspace firmware loading support
This changes the minimum required Linux version from 3.7 back to 3.0. [YOCTO #7409] (From OE-Core rev: 31163abc7bedd477c1aad10e6d1f47dbee194513) Signed-off-by: Jonathan Liu <net147@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-core/systemd/systemd')
-rw-r--r--meta/recipes-core/systemd/systemd/0014-Revert-rules-remove-firmware-loading-rules.patch28
-rw-r--r--meta/recipes-core/systemd/systemd/0015-Revert-udev-remove-userspace-firmware-loading-suppor.patch367
2 files changed, 395 insertions, 0 deletions
diff --git a/meta/recipes-core/systemd/systemd/0014-Revert-rules-remove-firmware-loading-rules.patch b/meta/recipes-core/systemd/systemd/0014-Revert-rules-remove-firmware-loading-rules.patch
new file mode 100644
index 0000000000..fe2ba5328d
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/0014-Revert-rules-remove-firmware-loading-rules.patch
@@ -0,0 +1,28 @@
1From 4f0a722489154da99e7f6b3051afde984eed2f74 Mon Sep 17 00:00:00 2001
2From: Jonathan Liu <net147@gmail.com>
3Date: Thu, 19 Mar 2015 15:01:29 +1100
4Subject: [PATCH] Revert "rules: remove firmware loading rules"
5
6This reverts commit 70e7d754ddb356fb1a2942b262f8cee9650e2a19.
7Userspace firmware loading support is needed for Linux < 3.7.
8
9Upstream-Status: Inappropriate [OE specific]
10
11Signed-off-by: Jonathan Liu <net147@gmail.com>
12---
13 rules/50-firmware.rules | 3 +++
14 1 file changed, 3 insertions(+)
15 create mode 100644 rules/50-firmware.rules
16
17diff --git a/rules/50-firmware.rules b/rules/50-firmware.rules
18new file mode 100644
19index 0000000..f0ae684
20--- /dev/null
21+++ b/rules/50-firmware.rules
22@@ -0,0 +1,3 @@
23+# do not edit this file, it will be overwritten on update
24+
25+SUBSYSTEM=="firmware", ACTION=="add", RUN{builtin}="firmware"
26--
272.3.3
28
diff --git a/meta/recipes-core/systemd/systemd/0015-Revert-udev-remove-userspace-firmware-loading-suppor.patch b/meta/recipes-core/systemd/systemd/0015-Revert-udev-remove-userspace-firmware-loading-suppor.patch
new file mode 100644
index 0000000000..3e3aa278bd
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/0015-Revert-udev-remove-userspace-firmware-loading-suppor.patch
@@ -0,0 +1,367 @@
1From 7f074def4e32045353ba4336d703e17b8de7ec4e Mon Sep 17 00:00:00 2001
2From: Jonathan Liu <net147@gmail.com>
3Date: Thu, 19 Mar 2015 15:01:33 +1100
4Subject: [PATCH] Revert "udev: remove userspace firmware loading support"
5
6This reverts commit be2ea723b1d023b3d385d3b791ee4607cbfb20ca.
7Userspace firmware loading support is needed for Linux < 3.7.
8
9Upstream-Status: Inappropriate [OE specific]
10
11Signed-off-by: Jonathan Liu <net147@gmail.com>
12---
13 Makefile.am | 12 +++
14 README | 9 ++-
15 TODO | 1 +
16 configure.ac | 20 +++++
17 src/udev/udev-builtin-firmware.c | 154 +++++++++++++++++++++++++++++++++++++++
18 src/udev/udev-builtin.c | 3 +
19 src/udev/udev.h | 6 ++
20 src/udev/udevd.c | 13 ++++
21 8 files changed, 214 insertions(+), 4 deletions(-)
22 create mode 100644 src/udev/udev-builtin-firmware.c
23
24diff --git a/Makefile.am b/Makefile.am
25index bf04d31..9394700 100644
26--- a/Makefile.am
27+++ b/Makefile.am
28@@ -3678,6 +3678,18 @@ libudev_core_la_LIBADD = \
29 $(BLKID_LIBS) \
30 $(KMOD_LIBS)
31
32+libudev_core_la_CPPFLAGS = \
33+ $(AM_CPPFLAGS) \
34+ -DFIRMWARE_PATH="$(FIRMWARE_PATH)"
35+
36+if ENABLE_FIRMWARE
37+libudev_core_la_SOURCES += \
38+ src/udev/udev-builtin-firmware.c
39+
40+dist_udevrules_DATA += \
41+ rules/50-firmware.rules
42+endif
43+
44 if HAVE_KMOD
45 libudev_core_la_SOURCES += \
46 src/udev/udev-builtin-kmod.c
47diff --git a/README b/README
48index c722092..db382d2 100644
49--- a/README
50+++ b/README
51@@ -36,7 +36,8 @@ LICENSE:
52 - except src/udev/* which is (currently still) GPLv2, GPLv2+
53
54 REQUIREMENTS:
55- Linux kernel >= 3.7
56+ Linux kernel >= 3.0
57+ Linux kernel >= 3.3 for loop device partition support features with nspawn
58 Linux kernel >= 3.8 for Smack support
59
60 Kernel Config Options:
61@@ -51,14 +52,14 @@ REQUIREMENTS:
62 CONFIG_PROC_FS
63 CONFIG_FHANDLE (libudev, mount and bind mount handling)
64
65- udev will fail to work with the legacy sysfs layout:
66+ Udev will fail to work with the legacy layout:
67 CONFIG_SYSFS_DEPRECATED=n
68
69 Legacy hotplug slows down the system and confuses udev:
70 CONFIG_UEVENT_HELPER_PATH=""
71
72- Userspace firmware loading is not supported and should
73- be disabled in the kernel:
74+ Userspace firmware loading is deprecated, will go away, and
75+ sometimes causes problems:
76 CONFIG_FW_LOADER_USER_HELPER=n
77
78 Some udev rules and virtualization detection relies on it:
79diff --git a/TODO b/TODO
80index 255a4f2..407bdd0 100644
81--- a/TODO
82+++ b/TODO
83@@ -727,6 +727,7 @@ Features:
84 * ExecOnFailure=/usr/bin/foo
85
86 * udev:
87+ - remove src/udev/udev-builtin-firmware.c (CONFIG_FW_LOADER_USER_HELPER=n)
88 - move to LGPL
89 - kill scsi_id
90 - add trigger --subsystem-match=usb/usb_device device
91diff --git a/configure.ac b/configure.ac
92index 97a29d6..13b80ce 100644
93--- a/configure.ac
94+++ b/configure.ac
95@@ -1245,6 +1245,25 @@ fi
96 AM_CONDITIONAL(HAVE_MYHOSTNAME, [test "$have_myhostname" = "yes"])
97
98 # ------------------------------------------------------------------------------
99+AC_ARG_WITH(firmware-path,
100+ AS_HELP_STRING([--with-firmware-path=DIR[[[:DIR[...]]]]],
101+ [Firmware search path (default="")]),
102+ [], [with_firmware_path=""])
103+OLD_IFS=$IFS
104+IFS=:
105+for i in $with_firmware_path; do
106+ if test "x${FIRMWARE_PATH}" = "x"; then
107+ FIRMWARE_PATH="\\\"${i}/\\\""
108+ else
109+ FIRMWARE_PATH="${FIRMWARE_PATH}, \\\"${i}/\\\""
110+ fi
111+done
112+IFS=$OLD_IFS
113+AC_SUBST(FIRMWARE_PATH)
114+AS_IF([test "x${FIRMWARE_PATH}" != "x"], [ AC_DEFINE(HAVE_FIRMWARE, 1, [Define if FIRMWARE is available]) ])
115+AM_CONDITIONAL(ENABLE_FIRMWARE, [test "x${FIRMWARE_PATH}" != "x"])
116+
117+# ------------------------------------------------------------------------------
118 AC_ARG_ENABLE([gudev],
119 AS_HELP_STRING([--disable-gudev], [disable Gobject libudev support @<:@default=enabled@:>@]),
120 [], [enable_gudev=yes])
121@@ -1533,6 +1552,7 @@ AC_MSG_RESULT([
122 Build Python: ${PYTHON}
123 Installation Python: ${PYTHON_BINARY}
124 sphinx binary: ${SPHINX_BUILD}
125+ firmware path: ${FIRMWARE_PATH}
126 PAM modules dir: ${with_pamlibdir}
127 PAM configuration dir: ${with_pamconfdir}
128 D-Bus policy dir: ${with_dbuspolicydir}
129diff --git a/src/udev/udev-builtin-firmware.c b/src/udev/udev-builtin-firmware.c
130new file mode 100644
131index 0000000..bd8c2fb
132--- /dev/null
133+++ b/src/udev/udev-builtin-firmware.c
134@@ -0,0 +1,154 @@
135+/*
136+ * firmware - Kernel firmware loader
137+ *
138+ * Copyright (C) 2009 Piter Punk <piterpunk@slackware.com>
139+ * Copyright (C) 2009-2011 Kay Sievers <kay@vrfy.org>
140+ *
141+ * This program is free software; you can redistribute it and/or
142+ * modify it under the terms of the GNU General Public License as
143+ * published by the Free Software Foundation; either version 2 of the
144+ * License, or (at your option) any later version.
145+ *
146+ * This program is distributed in the hope that it will be useful, but
147+ * WITHOUT ANY WARRANTY; without even the implied warranty of
148+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
149+ * General Public License for more details:*
150+ */
151+
152+#include <unistd.h>
153+#include <stdlib.h>
154+#include <string.h>
155+#include <stdio.h>
156+#include <getopt.h>
157+#include <errno.h>
158+#include <stdbool.h>
159+#include <sys/utsname.h>
160+#include <sys/stat.h>
161+
162+#include "udev.h"
163+
164+static bool set_loading(struct udev *udev, char *loadpath, const char *state) {
165+ FILE *ldfile;
166+
167+ ldfile = fopen(loadpath, "we");
168+ if (ldfile == NULL) {
169+ log_error("error: can not open '%s'", loadpath);
170+ return false;
171+ };
172+ fprintf(ldfile, "%s\n", state);
173+ fclose(ldfile);
174+ return true;
175+}
176+
177+static bool copy_firmware(struct udev *udev, const char *source, const char *target, size_t size) {
178+ char *buf;
179+ FILE *fsource = NULL, *ftarget = NULL;
180+ bool ret = false;
181+
182+ buf = malloc(size);
183+ if (buf == NULL) {
184+ log_error("No memory available to load firmware file");
185+ return false;
186+ }
187+
188+ log_debug("writing '%s' (%zi) to '%s'", source, size, target);
189+
190+ fsource = fopen(source, "re");
191+ if (fsource == NULL)
192+ goto exit;
193+ ftarget = fopen(target, "we");
194+ if (ftarget == NULL)
195+ goto exit;
196+ if (fread(buf, size, 1, fsource) != 1)
197+ goto exit;
198+ if (fwrite(buf, size, 1, ftarget) == 1)
199+ ret = true;
200+exit:
201+ if (ftarget != NULL)
202+ fclose(ftarget);
203+ if (fsource != NULL)
204+ fclose(fsource);
205+ free(buf);
206+ return ret;
207+}
208+
209+static int builtin_firmware(struct udev_device *dev, int argc, char *argv[], bool test) {
210+ struct udev *udev = udev_device_get_udev(dev);
211+ static const char *searchpath[] = { FIRMWARE_PATH };
212+ char loadpath[UTIL_PATH_SIZE];
213+ char datapath[UTIL_PATH_SIZE];
214+ char fwpath[UTIL_PATH_SIZE];
215+ const char *firmware;
216+ FILE *fwfile = NULL;
217+ struct utsname kernel;
218+ struct stat statbuf;
219+ unsigned int i;
220+ int rc = EXIT_SUCCESS;
221+
222+ firmware = udev_device_get_property_value(dev, "FIRMWARE");
223+ if (firmware == NULL) {
224+ log_error("firmware parameter missing");
225+ rc = EXIT_FAILURE;
226+ goto exit;
227+ }
228+
229+ /* lookup firmware file */
230+ uname(&kernel);
231+ for (i = 0; i < ELEMENTSOF(searchpath); i++) {
232+ strscpyl(fwpath, sizeof(fwpath), searchpath[i], kernel.release, "/", firmware, NULL);
233+ fwfile = fopen(fwpath, "re");
234+ if (fwfile != NULL)
235+ break;
236+
237+ strscpyl(fwpath, sizeof(fwpath), searchpath[i], firmware, NULL);
238+ fwfile = fopen(fwpath, "re");
239+ if (fwfile != NULL)
240+ break;
241+ }
242+
243+ strscpyl(loadpath, sizeof(loadpath), udev_device_get_syspath(dev), "/loading", NULL);
244+
245+ if (fwfile == NULL) {
246+ log_debug("did not find firmware file '%s'", firmware);
247+ rc = EXIT_FAILURE;
248+ /*
249+ * Do not cancel the request in the initrd, the real root might have
250+ * the firmware file and the 'coldplug' run in the real root will find
251+ * this pending request and fulfill or cancel it.
252+ * */
253+ if (!in_initrd())
254+ set_loading(udev, loadpath, "-1");
255+ goto exit;
256+ }
257+
258+ if (stat(fwpath, &statbuf) < 0 || statbuf.st_size == 0) {
259+ if (!in_initrd())
260+ set_loading(udev, loadpath, "-1");
261+ rc = EXIT_FAILURE;
262+ goto exit;
263+ }
264+
265+ if (!set_loading(udev, loadpath, "1"))
266+ goto exit;
267+
268+ strscpyl(datapath, sizeof(datapath), udev_device_get_syspath(dev), "/data", NULL);
269+ if (!copy_firmware(udev, fwpath, datapath, statbuf.st_size)) {
270+ log_error("error sending firmware '%s' to device", firmware);
271+ set_loading(udev, loadpath, "-1");
272+ rc = EXIT_FAILURE;
273+ goto exit;
274+ };
275+
276+ set_loading(udev, loadpath, "0");
277+exit:
278+ if (fwfile)
279+ fclose(fwfile);
280+ return rc;
281+}
282+
283+const struct udev_builtin udev_builtin_firmware = {
284+ .name = "firmware",
285+ .cmd = builtin_firmware,
286+ .help = "kernel firmware loader",
287+ .run_once = true,
288+};
289diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c
290index 1950ec2..f21c0b6 100644
291--- a/src/udev/udev-builtin.c
292+++ b/src/udev/udev-builtin.c
293@@ -34,6 +34,9 @@ static const struct udev_builtin *builtins[] = {
294 [UDEV_BUILTIN_BLKID] = &udev_builtin_blkid,
295 #endif
296 [UDEV_BUILTIN_BTRFS] = &udev_builtin_btrfs,
297+#ifdef HAVE_FIRMWARE
298+ [UDEV_BUILTIN_FIRMWARE] = &udev_builtin_firmware,
299+#endif
300 [UDEV_BUILTIN_HWDB] = &udev_builtin_hwdb,
301 [UDEV_BUILTIN_INPUT_ID] = &udev_builtin_input_id,
302 [UDEV_BUILTIN_KEYBOARD] = &udev_builtin_keyboard,
303diff --git a/src/udev/udev.h b/src/udev/udev.h
304index dece6ec..f7ee1e7 100644
305--- a/src/udev/udev.h
306+++ b/src/udev/udev.h
307@@ -151,6 +151,9 @@ enum udev_builtin_cmd {
308 UDEV_BUILTIN_BLKID,
309 #endif
310 UDEV_BUILTIN_BTRFS,
311+#ifdef HAVE_FIRMWARE
312+ UDEV_BUILTIN_FIRMWARE,
313+#endif
314 UDEV_BUILTIN_HWDB,
315 UDEV_BUILTIN_INPUT_ID,
316 UDEV_BUILTIN_KEYBOARD,
317@@ -179,6 +182,9 @@ struct udev_builtin {
318 extern const struct udev_builtin udev_builtin_blkid;
319 #endif
320 extern const struct udev_builtin udev_builtin_btrfs;
321+#ifdef HAVE_FIRMWARE
322+extern const struct udev_builtin udev_builtin_firmware;
323+#endif
324 extern const struct udev_builtin udev_builtin_hwdb;
325 extern const struct udev_builtin udev_builtin_input_id;
326 extern const struct udev_builtin udev_builtin_keyboard;
327diff --git a/src/udev/udevd.c b/src/udev/udevd.c
328index 99d4c89..71af1e1 100644
329--- a/src/udev/udevd.c
330+++ b/src/udev/udevd.c
331@@ -99,6 +99,9 @@ struct event {
332 dev_t devnum;
333 int ifindex;
334 bool is_block;
335+#ifdef HAVE_FIRMWARE
336+ bool nodelay;
337+#endif
338 };
339
340 static inline struct event *node_to_event(struct udev_list_node *node) {
341@@ -472,6 +475,10 @@ static int event_queue_insert(struct udev_device *dev) {
342 event->devnum = udev_device_get_devnum(dev);
343 event->is_block = streq("block", udev_device_get_subsystem(dev));
344 event->ifindex = udev_device_get_ifindex(dev);
345+#ifdef HAVE_FIRMWARE
346+ if (streq(udev_device_get_subsystem(dev), "firmware"))
347+ event->nodelay = true;
348+#endif
349
350 log_debug("seq %llu queued, '%s' '%s'", udev_device_get_seqnum(dev),
351 udev_device_get_action(dev), udev_device_get_subsystem(dev));
352@@ -548,6 +555,12 @@ static bool is_devpath_busy(struct event *event) {
353 return true;
354 }
355
356+#ifdef HAVE_FIRMWARE
357+ /* allow to bypass the dependency tracking */
358+ if (event->nodelay)
359+ continue;
360+#endif
361+
362 /* parent device event found */
363 if (event->devpath[common] == '/') {
364 event->delaying_seqnum = loop_event->seqnum;
365--
3662.3.3
367