History

Merge tag 'driver-core-3.7-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core

Pull driver core fixes from Greg Kroah-Hartman: "Here are a number of firmware core fixes for 3.7, and some other minor fixes. And some documentation updates thrown in for good measure. All have been in the linux-next tree for a while. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>" * tag 'driver-core-3.7-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: Documentation:Chinese translation of Documentation/arm64/memory.txt Documentation:Chinese translation of Documentation/arm64/booting.txt Documentation:Chinese translation of Documentation/IRQ.txt firmware loader: document kernel direct loading sysfs: sysfs_pathname/sysfs_add_one: Use strlcat() instead of strcat() dynamic_debug: Remove unnecessary __used firmware loader: sync firmware cache by async_synchronize_full_domain firmware loader: let direct loading back on 'firmware_buf' firmware loader: fix one reqeust_firmware race firmware loader: cancel uncache work before caching firmware

Linus Torvalds committed 14 years ago

Commit 299650c2 parents f76ddd9 bf34be07 files · +465 −133Browse files

Unified · Split

7 files
  1. Documentation/firmware_class/README +17 −9
  2. Documentation/zh_CN/IRQ.txt +39 −0
  3. Documentation/zh_CN/arm64/booting.txt +156 −0
  4. Documentation/zh_CN/arm64/memory.txt +93 −0
  5. drivers/base/firmware_class.c +151 −115
  6. fs/sysfs/dir.c +8 −8
  7. include/linux/dynamic_debug.h +1 −1
Documentation/firmware_class/README+17−9
@@ -18,32 +18,40 @@ · 17 unmodified lines
1818 High level behavior (mixed):
1919 ============================
2020
21− kernel(driver): calls request_firmware(&fw_entry, $FIRMWARE, device)
22−
23− userspace:
21+ 1), kernel(driver):
22+ - calls request_firmware(&fw_entry, $FIRMWARE, device)
23+ - kernel searchs the fimware image with name $FIRMWARE directly
24+ in the below search path of root filesystem:
25+ "/lib/firmware/updates/" UTS_RELEASE,
26+ "/lib/firmware/updates",
27+ "/lib/firmware/" UTS_RELEASE,
28+ "/lib/firmware"
29+ - If found, goto 7), else goto 2)
30+
31+ 2), userspace:
2432 - /sys/class/firmware/xxx/{loading,data} appear.
2533 - hotplug gets called with a firmware identifier in $FIRMWARE
2634 and the usual hotplug environment.
2735 - hotplug: echo 1 > /sys/class/firmware/xxx/loading
2836
29− kernel: Discard any previous partial load.
37+ 3), kernel: Discard any previous partial load.
3038
31− userspace:
39+ 4), userspace:
3240 - hotplug: cat appropriate_firmware_image > \
3341 /sys/class/firmware/xxx/data
3442
35− kernel: grows a buffer in PAGE_SIZE increments to hold the image as it
43+ 5), kernel: grows a buffer in PAGE_SIZE increments to hold the image as it
3644 comes in.
3745
38− userspace:
46+ 6), userspace:
3947 - hotplug: echo 0 > /sys/class/firmware/xxx/loading
4048
41− kernel: request_firmware() returns and the driver has the firmware
49+ 7), kernel: request_firmware() returns and the driver has the firmware
4250 image in fw_entry->{data,size}. If something went wrong
4351 request_firmware() returns non-zero and fw_entry is set to
4452 NULL.
4553
46− kernel(driver): Driver code calls release_firmware(fw_entry) releasing
54+ 8), kernel(driver): Driver code calls release_firmware(fw_entry) releasing
4755 the firmware image and any related resource.
4856
4957 High level behavior (driver code):
Documentation/zh_CN/IRQ.txt+39−0
@@ -0,0 +1,39 @@
1+Chinese translated version of Documentation/IRQ.txt
2+
3+If you have any comment or update to the content, please contact the
4+original document maintainer directly. However, if you have a problem
5+communicating in English you can also ask the Chinese maintainer for
6+help. Contact the Chinese maintainer if this translation is outdated
7+or if there is a problem with the translation.
8+
9+Maintainer: Eric W. Biederman <ebiederman@xmission.com>
10+Chinese maintainer: Fu Wei <tekkamanninja@gmail.com>
11+---------------------------------------------------------------------
12+Documentation/IRQ.txt 的中文翻译
13+
14+如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
15+交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
16+译存在问题,请联系中文版维护者。
17+英文版维护者: Eric W. Biederman <ebiederman@xmission.com>
18+中文版维护者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
19+中文版翻译者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
20+中文版校译者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
21+
22+
23+以下为正文
24+---------------------------------------------------------------------
25+何为 IRQ?
26+
27+一个 IRQ 是来自某个设备的一个中断请求。目前,它们可以来自一个硬件引脚,
28+或来自一个数据包。多个设备可能连接到同个硬件引脚,从而共享一个 IRQ。
29+
30+一个 IRQ 编号是用于告知硬件中断源的内核标识。通常情况下,这是一个
31+全局 irq_desc 数组的索引,但是除了在 linux/interrupt.h 中的实现,
32+具体的细节是体系结构特定的。
33+
34+一个 IRQ 编号是设备上某个可能的中断源的枚举。通常情况下,枚举的编号是
35+该引脚在系统内中断控制器的所有输入引脚中的编号。对于 ISA 总线中的情况,
36+枚举的是在两个 i8259 中断控制器中 16 个输入引脚。
37+
38+架构可以对 IRQ 编号指定额外的含义,在硬件涉及任何手工配置的情况下,
39+是被提倡的。ISA 的 IRQ 是一个分配这类额外含义的典型例子。
Documentation/zh_CN/arm64/booting.txt+156−0
@@ -0,0 +1,156 @@
1+Chinese translated version of Documentation/arm64/booting.txt
2+
3+If you have any comment or update to the content, please contact the
4+original document maintainer directly. However, if you have a problem
5+communicating in English you can also ask the Chinese maintainer for
6+help. Contact the Chinese maintainer if this translation is outdated
7+or if there is a problem with the translation.
8+
9+Maintainer: Will Deacon <will.deacon@arm.com>
10+Chinese maintainer: Fu Wei <tekkamanninja@gmail.com>
11+---------------------------------------------------------------------
12+Documentation/arm64/booting.txt 的中文翻译
13+
14+如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
15+交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
16+译存在问题,请联系中文版维护者。
17+
18+英文版维护者: Will Deacon <will.deacon@arm.com>
19+中文版维护者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
20+中文版翻译者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
21+中文版校译者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
22+
23+以下为正文
24+---------------------------------------------------------------------
25+ 启动 AArch64 Linux
26+ ==================
27+
28+作者: Will Deacon <will.deacon@arm.com>
29+日期: 2012 年 09 月 07 日
30+
31+本文档基于 Russell King 的 ARM 启动文档,且适用于所有公开发布的
32+AArch64 Linux 内核代码。
33+
34+AArch64 异常模型由多个异常级别(EL0 - EL3)组成,对于 EL0 和 EL1
35+异常级有对应的安全和非安全模式。EL2 是系统管理级,且仅存在于
36+非安全模式下。EL3 是最高特权级,且仅存在于安全模式下。
37+
38+基于本文档的目的,我们将简单地使用‘引导装载程序’(‘boot loader’)
39+这个术语来定义在将控制权交给 Linux 内核前 CPU 上执行的所有软件。
40+这可能包含安全监控和系统管理代码,或者它可能只是一些用于准备最小启动
41+环境的指令。
42+
43+基本上,引导装载程序(至少)应实现以下操作:
44+
45+1、设置和初始化 RAM
46+2、设置设备树数据
47+3、解压内核映像
48+4、调用内核映像
49+
50+
51+1、设置和初始化 RAM
52+-----------------
53+
54+必要性: 强制
55+
56+引导装载程序应该找到并初始化系统中所有内核用于保持系统变量数据的 RAM。
57+这个操作的执行是设备依赖的。(它可能使用内部算法来自动定位和计算所有
58+RAM,或可能使用对这个设备已知的 RAM 信息,还可能使用任何引导装载程序
59+设计者想到的匹配方法。)
60+
61+
62+2、设置设备树数据
63+---------------
64+
65+必要性: 强制
66+
67+设备树数据块(dtb)大小必须不大于 2 MB,且位于从内核映像起始算起第一个
68+512MB 内的 2MB 边界上。这使得内核可以通过初始页表中的单个节描述符来
69+映射此数据块。
70+
71+
72+3、解压内核映像
73+-------------
74+
75+必要性: 可选
76+
77+AArch64 内核当前没有提供自解压代码,因此如果使用了压缩内核映像文件
78+(比如 Image.gz),则需要通过引导装载程序(使用 gzip 等)来进行解压。
79+若引导装载程序没有实现这个需求,就要使用非压缩内核映像文件。
80+
81+
82+4、调用内核映像
83+-------------
84+
85+必要性: 强制
86+
87+已解压的内核映像包含一个 32 字节的头,内容如下:
88+
89+ u32 magic = 0x14000008; /* 跳转到 stext, 小端 */
90+ u32 res0 = 0; /* 保留 */
91+ u64 text_offset; /* 映像装载偏移 */
92+ u64 res1 = 0; /* 保留 */
93+ u64 res2 = 0; /* 保留 */
94+
95+映像必须位于系统 RAM 起始处的特定偏移(当前是 0x80000)。系统 RAM
96+的起始地址必须是以 2MB 对齐的。
97+
98+在跳转入内核前,必须符合以下状态:
99+
100+- 停止所有 DMA 设备,这样内存数据就不会因为虚假网络包或磁盘数据而
101+ 被破坏。这可能可以节省你许多的调试时间。
102+
103+- 主 CPU 通用寄存器设置
104+ x0 = 系统 RAM 中设备树数据块(dtb)的物理地址。
105+ x1 = 0 (保留,将来可能使用)
106+ x2 = 0 (保留,将来可能使用)
107+ x3 = 0 (保留,将来可能使用)
108+
109+- CPU 模式
110+ 所有形式的中断必须在 PSTATE.DAIF 中被屏蔽(Debug、SError、IRQ
111+ 和 FIQ)。
112+ CPU 必须处于 EL2(推荐,可访问虚拟化扩展)或非安全 EL1 模式下。
113+
114+- 高速缓存、MMU
115+ MMU 必须关闭。
116+ 指令缓存开启或关闭都可以。
117+ 数据缓存必须关闭且无效。
118+ 外部高速缓存(如果存在)必须配置并禁用。
119+
120+- 架构计时器
121+ CNTFRQ 必须设定为计时器的频率。
122+ 如果在 EL1 模式下进入内核,则 CNTHCTL_EL2 中的 EL1PCTEN (bit 0)
123+ 必须置位。
124+
125+- 一致性
126+ 通过内核启动的所有 CPU 在内核入口地址上必须处于相同的一致性域中。
127+ 这可能要根据具体实现来定义初始化过程,以使能每个CPU上对维护操作的
128+ 接收。
129+
130+- 系统寄存器
131+ 在进入内核映像的异常级中,所有构架中可写的系统寄存器必须通过软件
132+ 在一个更高的异常级别下初始化,以防止在 未知 状态下运行。
133+
134+引导装载程序必须在每个 CPU 处于以下状态时跳入内核入口:
135+
136+- 主 CPU 必须直接跳入内核映像的第一条指令。通过此 CPU 传递的设备树
137+ 数据块必须在每个 CPU 节点中包含以下内容:
138+
139+ 1、‘enable-method’属性。目前,此字段支持的值仅为字符串“spin-table”。
140+
141+ 2、‘cpu-release-addr’标识一个 64-bit、初始化为零的内存位置。
142+
143+ 引导装载程序必须生成这些设备树属性,并在跳入内核入口之前将其插入
144+ 数据块。
145+
146+- 任何辅助 CPU 必须在内存保留区(通过设备树中的 /memreserve/ 域传递
147+ 给内核)中自旋于内核之外,轮询它们的 cpu-release-addr 位置(必须
148+ 包含在保留区中)。可通过插入 wfe 指令来降低忙循环开销,而主 CPU 将
149+ 发出 sev 指令。当对 cpu-release-addr 所指位置的读取操作返回非零值
150+ 时,CPU 必须直接跳入此值所指向的地址。
151+
152+- 辅助 CPU 通用寄存器设置
153+ x0 = 0 (保留,将来可能使用)
154+ x1 = 0 (保留,将来可能使用)
155+ x2 = 0 (保留,将来可能使用)
156+ x3 = 0 (保留,将来可能使用)
Documentation/zh_CN/arm64/memory.txt+93−0
@@ -0,0 +1,93 @@
1+Chinese translated version of Documentation/arm64/memory.txt
2+
3+If you have any comment or update to the content, please contact the
4+original document maintainer directly. However, if you have a problem
5+communicating in English you can also ask the Chinese maintainer for
6+help. Contact the Chinese maintainer if this translation is outdated
7+or if there is a problem with the translation.
8+
9+Maintainer: Catalin Marinas <catalin.marinas@arm.com>
10+Chinese maintainer: Fu Wei <tekkamanninja@gmail.com>
11+---------------------------------------------------------------------
12+Documentation/arm64/memory.txt 的中文翻译
13+
14+如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
15+交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
16+译存在问题,请联系中文版维护者。
17+
18+英文版维护者: Catalin Marinas <catalin.marinas@arm.com>
19+中文版维护者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
20+中文版翻译者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
21+中文版校译者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
22+
23+以下为正文
24+---------------------------------------------------------------------
25+ Linux 在 AArch64 中的内存布局
26+ ===========================
27+
28+作者: Catalin Marinas <catalin.marinas@arm.com>
29+日期: 2012 年 02 月 20 日
30+
31+本文档描述 AArch64 Linux 内核所使用的虚拟内存布局。此构架可以实现
32+页大小为 4KB 的 4 级转换表和页大小为 64KB 的 3 级转换表。
33+
34+AArch64 Linux 使用页大小为 4KB 的 3 级转换表配置,对于用户和内核
35+都有 39-bit (512GB) 的虚拟地址空间。对于页大小为 64KB的配置,仅
36+使用 2 级转换表,但内存布局相同。
37+
38+用户地址空间的 63:39 位为 0,而内核地址空间的相应位为 1。TTBRx 的
39+选择由虚拟地址的 63 位给出。swapper_pg_dir 仅包含内核(全局)映射,
40+而用户 pgd 仅包含用户(非全局)映射。swapper_pgd_dir 地址被写入
41+TTBR1 中,且从不写入 TTBR0。
42+
43+
44+AArch64 Linux 内存布局:
45+
46+起始地址 结束地址 大小 用途
47+-----------------------------------------------------------------------
48+0000000000000000 0000007fffffffff 512GB 用户空间
49+
50+ffffff8000000000 ffffffbbfffcffff ~240GB vmalloc
51+
52+ffffffbbfffd0000 ffffffbcfffdffff 64KB [防护页]
53+
54+ffffffbbfffe0000 ffffffbcfffeffff 64KB PCI I/O 空间
55+
56+ffffffbbffff0000 ffffffbcffffffff 64KB [防护页]
57+
58+ffffffbc00000000 ffffffbdffffffff 8GB vmemmap
59+
60+ffffffbe00000000 ffffffbffbffffff ~8GB [防护页,未来用于 vmmemap]
61+
62+ffffffbffc000000 ffffffbfffffffff 64MB 模块
63+
64+ffffffc000000000 ffffffffffffffff 256GB 内存空间
65+
66+
67+4KB 页大小的转换表查找:
68+
69++--------+--------+--------+--------+--------+--------+--------+--------+
70+|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
71++--------+--------+--------+--------+--------+--------+--------+--------+
72+ | | | | | |
73+ | | | | | v
74+ | | | | | [11:0] 页内偏移
75+ | | | | +-> [20:12] L3 索引
76+ | | | +-----------> [29:21] L2 索引
77+ | | +---------------------> [38:30] L1 索引
78+ | +-------------------------------> [47:39] L0 索引 (未使用)
79+ +-------------------------------------------------> [63] TTBR0/1
80+
81+
82+64KB 页大小的转换表查找:
83+
84++--------+--------+--------+--------+--------+--------+--------+--------+
85+|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
86++--------+--------+--------+--------+--------+--------+--------+--------+
87+ | | | | |
88+ | | | | v
89+ | | | | [15:0] 页内偏移
90+ | | | +----------> [28:16] L3 索引
91+ | | +--------------------------> [41:29] L2 索引 (仅使用 38:29 )
92+ | +-------------------------------> [47:42] L1 索引 (未使用)
93+ +-------------------------------------------------> [63] TTBR0/1
drivers/base/firmware_class.c+151−115
@@ -36,68 +36,6 @@ MODULE_AUTHOR("Manuel Estrada Sainz"); · 35 unmodified lines
3636 MODULE_DESCRIPTION("Multi purpose firmware loading support");
3737 MODULE_LICENSE("GPL");
3838
39−static const char *fw_path[] = {
40− "/lib/firmware/updates/" UTS_RELEASE,
41− "/lib/firmware/updates",
42− "/lib/firmware/" UTS_RELEASE,
43− "/lib/firmware"
44−};
45−
46−/* Don't inline this: 'struct kstat' is biggish */
47−static noinline long fw_file_size(struct file *file)
48−{
49− struct kstat st;
50− if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st))
51− return -1;
52− if (!S_ISREG(st.mode))
53− return -1;
54− if (st.size != (long)st.size)
55− return -1;
56− return st.size;
57−}
58−
59−static bool fw_read_file_contents(struct file *file, struct firmware *fw)
60−{
61− long size;
62− char *buf;
63−
64− size = fw_file_size(file);
65− if (size < 0)
66− return false;
67− buf = vmalloc(size);
68− if (!buf)
69− return false;
70− if (kernel_read(file, 0, buf, size) != size) {
71− vfree(buf);
72− return false;
73− }
74− fw->data = buf;
75− fw->size = size;
76− return true;
77−}
78−
79−static bool fw_get_filesystem_firmware(struct firmware *fw, const char *name)
80−{
81− int i;
82− bool success = false;
83− char *path = __getname();
84−
85− for (i = 0; i < ARRAY_SIZE(fw_path); i++) {
86− struct file *file;
87− snprintf(path, PATH_MAX, "%s/%s", fw_path[i], name);
88−
89− file = filp_open(path, O_RDONLY, 0);
90− if (IS_ERR(file))
91− continue;
92− success = fw_read_file_contents(file, fw);
93− fput(file);
94− if (success)
95− break;
96− }
97− __putname(path);
98− return success;
99−}
100−
10139 /* Builtin firmware support */
10240
10341 #ifdef CONFIG_FW_LOADER
@@ -150,6 +88,11 @@ enum { · 46 unmodified lines
15088 FW_STATUS_ABORT,
15189 };
15290
91+enum fw_buf_fmt {
92+ VMALLOC_BUF, /* used in direct loading */
93+ PAGE_BUF, /* used in loading via userspace */
94+};
95+
15396 static int loading_timeout = 60; /* In seconds */
15497
15598 static inline long firmware_loading_timeout(void)
@@ -173,8 +116,6 @@ struct firmware_cache { · 17 unmodified lines
173116 spinlock_t name_lock;
174117 struct list_head fw_names;
175118
176− wait_queue_head_t wait_queue;
177− int cnt;
178119 struct delayed_work work;
179120
180121 struct notifier_block pm_notify;
@@ -187,6 +128,7 @@ struct firmware_buf { · 6 unmodified lines
187128 struct completion completion;
188129 struct firmware_cache *fwc;
189130 unsigned long status;
131+ enum fw_buf_fmt fmt;
190132 void *data;
191133 size_t size;
192134 struct page **pages;
@@ -240,6 +182,7 @@ static struct firmware_buf *__allocate_fw_buf(const char *fw_name, · 47 unmodified lines
240182 strcpy(buf->fw_id, fw_name);
241183 buf->fwc = fwc;
242184 init_completion(&buf->completion);
185+ buf->fmt = VMALLOC_BUF;
243186
244187 pr_debug("%s: fw-%s buf=%p\n", __func__, fw_name, buf);
245188
@@ -307,10 +250,14 @@ static void __fw_free_buf(struct kref *ref) · 61 unmodified lines
307250 list_del(&buf->list);
308251 spin_unlock(&fwc->lock);
309252
310− vunmap(buf->data);
311− for (i = 0; i < buf->nr_pages; i++)
312− __free_page(buf->pages[i]);
313− kfree(buf->pages);
253+
254+ if (buf->fmt == PAGE_BUF) {
255+ vunmap(buf->data);
256+ for (i = 0; i < buf->nr_pages; i++)
257+ __free_page(buf->pages[i]);
258+ kfree(buf->pages);
259+ } else
260+ vfree(buf->data);
314261 kfree(buf);
315262 }
316263
@@ -319,6 +266,69 @@ static void fw_free_buf(struct firmware_buf *buf) · 2 unmodified lines
319266 kref_put(&buf->ref, __fw_free_buf);
320267 }
321268
269+/* direct firmware loading support */
270+static const char *fw_path[] = {
271+ "/lib/firmware/updates/" UTS_RELEASE,
272+ "/lib/firmware/updates",
273+ "/lib/firmware/" UTS_RELEASE,
274+ "/lib/firmware"
275+};
276+
277+/* Don't inline this: 'struct kstat' is biggish */
278+static noinline long fw_file_size(struct file *file)
279+{
280+ struct kstat st;
281+ if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st))
282+ return -1;
283+ if (!S_ISREG(st.mode))
284+ return -1;
285+ if (st.size != (long)st.size)
286+ return -1;
287+ return st.size;
288+}
289+
290+static bool fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
291+{
292+ long size;
293+ char *buf;
294+
295+ size = fw_file_size(file);
296+ if (size < 0)
297+ return false;
298+ buf = vmalloc(size);
299+ if (!buf)
300+ return false;
301+ if (kernel_read(file, 0, buf, size) != size) {
302+ vfree(buf);
303+ return false;
304+ }
305+ fw_buf->data = buf;
306+ fw_buf->size = size;
307+ return true;
308+}
309+
310+static bool fw_get_filesystem_firmware(struct firmware_buf *buf)
311+{
312+ int i;
313+ bool success = false;
314+ char *path = __getname();
315+
316+ for (i = 0; i < ARRAY_SIZE(fw_path); i++) {
317+ struct file *file;
318+ snprintf(path, PATH_MAX, "%s/%s", fw_path[i], buf->fw_id);
319+
320+ file = filp_open(path, O_RDONLY, 0);
321+ if (IS_ERR(file))
322+ continue;
323+ success = fw_read_file_contents(file, buf);
324+ fput(file);
325+ if (success)
326+ break;
327+ }
328+ __putname(path);
329+ return success;
330+}
331+
322332 static struct firmware_priv *to_firmware_priv(struct device *dev)
323333 {
324334 return container_of(dev, struct firmware_priv, dev);
@@ -423,6 +433,21 @@ static void firmware_free_data(const struct firmware *fw) · 98 unmodified lines
423433 #ifndef PAGE_KERNEL_RO
424434 #define PAGE_KERNEL_RO PAGE_KERNEL
425435 #endif
436+
437+/* one pages buffer should be mapped/unmapped only once */
438+static int fw_map_pages_buf(struct firmware_buf *buf)
439+{
440+ if (buf->fmt != PAGE_BUF)
441+ return 0;
442+
443+ if (buf->data)
444+ vunmap(buf->data);
445+ buf->data = vmap(buf->pages, buf->nr_pages, 0, PAGE_KERNEL_RO);
446+ if (!buf->data)
447+ return -ENOMEM;
448+ return 0;
449+}
450+
426451 /**
427452 * firmware_loading_store - set value in the 'loading' control file
428453 * @dev: device pointer
@@ -467,6 +492,14 @@ static ssize_t firmware_loading_store(struct device *dev, · 38 unmodified lines
467492 if (test_bit(FW_STATUS_LOADING, &fw_buf->status)) {
468493 set_bit(FW_STATUS_DONE, &fw_buf->status);
469494 clear_bit(FW_STATUS_LOADING, &fw_buf->status);
495+
496+ /*
497+ * Several loading requests may be pending on
498+ * one same firmware buf, so let all requests
499+ * see the mapped 'buf->data' once the loading
500+ * is completed.
501+ * */
502+ fw_map_pages_buf(fw_buf);
470503 complete_all(&fw_buf->completion);
471504 break;
472505 }
@@ -670,15 +703,6 @@ exit: · 197 unmodified lines
670703 return fw_priv;
671704 }
672705
673−/* one pages buffer is mapped/unmapped only once */
674−static int fw_map_pages_buf(struct firmware_buf *buf)
675−{
676− buf->data = vmap(buf->pages, buf->nr_pages, 0, PAGE_KERNEL_RO);
677− if (!buf->data)
678− return -ENOMEM;
679− return 0;
680−}
681−
682706 /* store the pages buffer info firmware from buf */
683707 static void fw_set_page_data(struct firmware_buf *buf, struct firmware *fw)
684708 {
@@ -778,11 +802,6 @@ _request_firmware_prepare(const struct firmware **firmware_p, const char *name, · 93 unmodified lines
778802 return NULL;
779803 }
780804
781− if (fw_get_filesystem_firmware(firmware, name)) {
782− dev_dbg(device, "firmware: direct-loading firmware %s\n", name);
783− return NULL;
784− }
785−
786805 ret = fw_lookup_and_allocate_buf(name, &fw_cache, &buf);
787806 if (!ret)
788807 fw_priv = fw_create_instance(firmware, name, device,
@@ -832,6 +851,21 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, · 43 unmodified lines
832851 struct device *f_dev = &fw_priv->dev;
833852 struct firmware_buf *buf = fw_priv->buf;
834853 struct firmware_cache *fwc = &fw_cache;
854+ int direct_load = 0;
855+
856+ /* try direct loading from fs first */
857+ if (fw_get_filesystem_firmware(buf)) {
858+ dev_dbg(f_dev->parent, "firmware: direct-loading"
859+ " firmware %s\n", buf->fw_id);
860+
861+ set_bit(FW_STATUS_DONE, &buf->status);
862+ complete_all(&buf->completion);
863+ direct_load = 1;
864+ goto handle_fw;
865+ }
866+
867+ /* fall back on userspace loading */
868+ buf->fmt = PAGE_BUF;
835869
836870 dev_set_uevent_suppress(f_dev, true);
837871
@@ -870,6 +904,7 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, · 32 unmodified lines
870904
871905 del_timer_sync(&fw_priv->timeout);
872906
907+handle_fw:
873908 mutex_lock(&fw_lock);
874909 if (!buf->size || test_bit(FW_STATUS_ABORT, &buf->status))
875910 retval = -ENOENT;
@@ -884,9 +919,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, · 8 unmodified lines
884919 if (!retval && f_dev->parent)
885920 fw_add_devm_name(f_dev->parent, buf->fw_id);
886921
887− if (!retval)
888− retval = fw_map_pages_buf(buf);
889−
890922 /*
891923 * After caching firmware image is started, let it piggyback
892924 * on request firmware.
@@ -902,6 +934,9 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, · 9 unmodified lines
902934 fw_priv->buf = NULL;
903935 mutex_unlock(&fw_lock);
904936
937+ if (direct_load)
938+ goto err_put_dev;
939+
905940 device_remove_file(f_dev, &dev_attr_loading);
906941 err_del_bin_attr:
907942 device_remove_bin_file(f_dev, &firmware_attr_data);
@@ -1129,6 +1164,8 @@ int uncache_firmware(const char *fw_name) · 221 unmodified lines
11291164 }
11301165
11311166 #ifdef CONFIG_PM_SLEEP
1167+static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain);
1168+
11321169 static struct fw_cache_entry *alloc_fw_cache_entry(const char *name)
11331170 {
11341171 struct fw_cache_entry *fce;
@@ -1142,17 +1179,27 @@ exit: · 7 unmodified lines
11421179 return fce;
11431180 }
11441181
1145−static int fw_cache_piggyback_on_request(const char *name)
1182+static int __fw_entry_found(const char *name)
11461183 {
11471184 struct firmware_cache *fwc = &fw_cache;
11481185 struct fw_cache_entry *fce;
1149− int ret = 0;
11501186
1151− spin_lock(&fwc->name_lock);
11521187 list_for_each_entry(fce, &fwc->fw_names, list) {
11531188 if (!strcmp(fce->name, name))
1154− goto found;
1189+ return 1;
11551190 }
1191+ return 0;
1192+}
1193+
1194+static int fw_cache_piggyback_on_request(const char *name)
1195+{
1196+ struct firmware_cache *fwc = &fw_cache;
1197+ struct fw_cache_entry *fce;
1198+ int ret = 0;
1199+
1200+ spin_lock(&fwc->name_lock);
1201+ if (__fw_entry_found(name))
1202+ goto found;
11561203
11571204 fce = alloc_fw_cache_entry(name);
11581205 if (fce) {
@@ -1185,12 +1232,6 @@ static void __async_dev_cache_fw_image(void *fw_entry, · 26 unmodified lines
11851232
11861233 free_fw_cache_entry(fce);
11871234 }
1188−
1189− spin_lock(&fwc->name_lock);
1190− fwc->cnt--;
1191− spin_unlock(&fwc->name_lock);
1192−
1193− wake_up(&fwc->wait_queue);
11941235 }
11951236
11961237 /* called with dev->devres_lock held */
@@ -1229,11 +1270,19 @@ static void dev_cache_fw_image(struct device *dev, void *data) · 32 unmodified lines
12291270 list_del(&fce->list);
12301271
12311272 spin_lock(&fwc->name_lock);
1232− fwc->cnt++;
1233− list_add(&fce->list, &fwc->fw_names);
1273+ /* only one cache entry for one firmware */
1274+ if (!__fw_entry_found(fce->name)) {
1275+ list_add(&fce->list, &fwc->fw_names);
1276+ } else {
1277+ free_fw_cache_entry(fce);
1278+ fce = NULL;
1279+ }
12341280 spin_unlock(&fwc->name_lock);
12351281
1236− async_schedule(__async_dev_cache_fw_image, (void *)fce);
1282+ if (fce)
1283+ async_schedule_domain(__async_dev_cache_fw_image,
1284+ (void *)fce,
1285+ &fw_cache_domain);
12371286 }
12381287 }
12391288
@@ -1275,6 +1324,9 @@ static void device_cache_fw_images(void) · 35 unmodified lines
12751324
12761325 pr_debug("%s\n", __func__);
12771326
1327+ /* cancel uncache work */
1328+ cancel_delayed_work_sync(&fwc->work);
1329+
12781330 /*
12791331 * use small loading timeout for caching devices' firmware
12801332 * because all these firmware images have been loaded
@@ -1292,21 +1344,7 @@ static void device_cache_fw_images(void) · 11 unmodified lines
12921344 mutex_unlock(&fw_lock);
12931345
12941346 /* wait for completion of caching firmware for all devices */
1295− spin_lock(&fwc->name_lock);
1296− for (;;) {
1297− prepare_to_wait(&fwc->wait_queue, &wait,
1298− TASK_UNINTERRUPTIBLE);
1299− if (!fwc->cnt)
1300− break;
1301−
1302− spin_unlock(&fwc->name_lock);
1303−
1304− schedule();
1305−
1306− spin_lock(&fwc->name_lock);
1307− }
1308− spin_unlock(&fwc->name_lock);
1309− finish_wait(&fwc->wait_queue, &wait);
1347+ async_synchronize_full_domain(&fw_cache_domain);
13101348
13111349 loading_timeout = old_timeout;
13121350 }
@@ -1394,9 +1432,7 @@ static void __init fw_cache_init(void) · 81 unmodified lines
13941432 #ifdef CONFIG_PM_SLEEP
13951433 spin_lock_init(&fw_cache.name_lock);
13961434 INIT_LIST_HEAD(&fw_cache.fw_names);
1397− fw_cache.cnt = 0;
13981435
1399− init_waitqueue_head(&fw_cache.wait_queue);
14001436 INIT_DELAYED_WORK(&fw_cache.work,
14011437 device_uncache_fw_images_work);
14021438
fs/sysfs/dir.c+8−8
@@ -485,20 +485,18 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) · 484 unmodified lines
485485 /**
486486 * sysfs_pathname - return full path to sysfs dirent
487487 * @sd: sysfs_dirent whose path we want
488− * @path: caller allocated buffer
488+ * @path: caller allocated buffer of size PATH_MAX
489489 *
490490 * Gives the name "/" to the sysfs_root entry; any path returned
491491 * is relative to wherever sysfs is mounted.
492− *
493− * XXX: does no error checking on @path size
494492 */
495493 static char *sysfs_pathname(struct sysfs_dirent *sd, char *path)
496494 {
497495 if (sd->s_parent) {
498496 sysfs_pathname(sd->s_parent, path);
499− strcat(path, "/");
497+ strlcat(path, "/", PATH_MAX);
500498 }
501− strcat(path, sd->s_name);
499+ strlcat(path, sd->s_name, PATH_MAX);
502500 return path;
503501 }
504502
@@ -531,9 +529,11 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) · 26 unmodified lines
531529 char *path = kzalloc(PATH_MAX, GFP_KERNEL);
532530 WARN(1, KERN_WARNING
533531 "sysfs: cannot create duplicate filename '%s'\n",
534− (path == NULL) ? sd->s_name :
535− strcat(strcat(sysfs_pathname(acxt->parent_sd, path), "/"),
536− sd->s_name));
532+ (path == NULL) ? sd->s_name
533+ : (sysfs_pathname(acxt->parent_sd, path),
534+ strlcat(path, "/", PATH_MAX),
535+ strlcat(path, sd->s_name, PATH_MAX),
536+ path));
537537 kfree(path);
538538 }
539539
include/linux/dynamic_debug.h+1−1
@@ -61,7 +61,7 @@ int __dynamic_netdev_dbg(struct _ddebug *descriptor, · 60 unmodified lines
6161 const char *fmt, ...);
6262
6363 #define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
64− static struct _ddebug __used __aligned(8) \
64+ static struct _ddebug __aligned(8) \
6565 __attribute__((section("__verbose"))) name = { \
6666 .modname = KBUILD_MODNAME, \
6767 .function = __func__, \