Contents of /trunk/kernel-alx/patches-3.8/0105-3.8.6-all-fixes.patch
Parent Directory | Revision Log
Revision 2154 -
(show annotations)
(download)
Tue Apr 16 06:32:36 2013 UTC (11 years, 5 months ago) by niro
File size: 186429 byte(s)
Tue Apr 16 06:32:36 2013 UTC (11 years, 5 months ago) by niro
File size: 186429 byte(s)
-linux-3.8.6
1 | diff --git a/arch/arm/boot/dts/kirkwood-goflexnet.dts b/arch/arm/boot/dts/kirkwood-goflexnet.dts |
2 | index bd83b8f..c3573be 100644 |
3 | --- a/arch/arm/boot/dts/kirkwood-goflexnet.dts |
4 | +++ b/arch/arm/boot/dts/kirkwood-goflexnet.dts |
5 | @@ -77,6 +77,7 @@ |
6 | }; |
7 | |
8 | nand@3000000 { |
9 | + chip-delay = <40>; |
10 | status = "okay"; |
11 | |
12 | partition@0 { |
13 | diff --git a/arch/arm/include/asm/signal.h b/arch/arm/include/asm/signal.h |
14 | index 9a0ea6a..7f79136 100644 |
15 | --- a/arch/arm/include/asm/signal.h |
16 | +++ b/arch/arm/include/asm/signal.h |
17 | @@ -29,6 +29,7 @@ struct sigaction { |
18 | __sigrestore_t sa_restorer; |
19 | sigset_t sa_mask; /* mask last for extensibility */ |
20 | }; |
21 | +#define __ARCH_HAS_SA_RESTORER |
22 | |
23 | struct k_sigaction { |
24 | struct sigaction sa; |
25 | diff --git a/arch/arm/mach-cns3xxx/core.c b/arch/arm/mach-cns3xxx/core.c |
26 | index 031805b..7f26faf 100644 |
27 | --- a/arch/arm/mach-cns3xxx/core.c |
28 | +++ b/arch/arm/mach-cns3xxx/core.c |
29 | @@ -22,19 +22,9 @@ |
30 | |
31 | static struct map_desc cns3xxx_io_desc[] __initdata = { |
32 | { |
33 | - .virtual = CNS3XXX_TC11MP_TWD_BASE_VIRT, |
34 | - .pfn = __phys_to_pfn(CNS3XXX_TC11MP_TWD_BASE), |
35 | - .length = SZ_4K, |
36 | - .type = MT_DEVICE, |
37 | - }, { |
38 | - .virtual = CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT, |
39 | - .pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_CPU_BASE), |
40 | - .length = SZ_4K, |
41 | - .type = MT_DEVICE, |
42 | - }, { |
43 | - .virtual = CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT, |
44 | - .pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_DIST_BASE), |
45 | - .length = SZ_4K, |
46 | + .virtual = CNS3XXX_TC11MP_SCU_BASE_VIRT, |
47 | + .pfn = __phys_to_pfn(CNS3XXX_TC11MP_SCU_BASE), |
48 | + .length = SZ_8K, |
49 | .type = MT_DEVICE, |
50 | }, { |
51 | .virtual = CNS3XXX_TIMER1_2_3_BASE_VIRT, |
52 | diff --git a/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h |
53 | index 191c8e5..b1021aa 100644 |
54 | --- a/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h |
55 | +++ b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h |
56 | @@ -94,10 +94,10 @@ |
57 | #define RTC_INTR_STS_OFFSET 0x34 |
58 | |
59 | #define CNS3XXX_MISC_BASE 0x76000000 /* Misc Control */ |
60 | -#define CNS3XXX_MISC_BASE_VIRT 0xFFF07000 /* Misc Control */ |
61 | +#define CNS3XXX_MISC_BASE_VIRT 0xFB000000 /* Misc Control */ |
62 | |
63 | #define CNS3XXX_PM_BASE 0x77000000 /* Power Management Control */ |
64 | -#define CNS3XXX_PM_BASE_VIRT 0xFFF08000 |
65 | +#define CNS3XXX_PM_BASE_VIRT 0xFB001000 |
66 | |
67 | #define PM_CLK_GATE_OFFSET 0x00 |
68 | #define PM_SOFT_RST_OFFSET 0x04 |
69 | @@ -109,7 +109,7 @@ |
70 | #define PM_PLL_HM_PD_OFFSET 0x1C |
71 | |
72 | #define CNS3XXX_UART0_BASE 0x78000000 /* UART 0 */ |
73 | -#define CNS3XXX_UART0_BASE_VIRT 0xFFF09000 |
74 | +#define CNS3XXX_UART0_BASE_VIRT 0xFB002000 |
75 | |
76 | #define CNS3XXX_UART1_BASE 0x78400000 /* UART 1 */ |
77 | #define CNS3XXX_UART1_BASE_VIRT 0xFFF0A000 |
78 | @@ -130,7 +130,7 @@ |
79 | #define CNS3XXX_I2S_BASE_VIRT 0xFFF10000 |
80 | |
81 | #define CNS3XXX_TIMER1_2_3_BASE 0x7C800000 /* Timer */ |
82 | -#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFFF10800 |
83 | +#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFB003000 |
84 | |
85 | #define TIMER1_COUNTER_OFFSET 0x00 |
86 | #define TIMER1_AUTO_RELOAD_OFFSET 0x04 |
87 | @@ -227,16 +227,16 @@ |
88 | * Testchip peripheral and fpga gic regions |
89 | */ |
90 | #define CNS3XXX_TC11MP_SCU_BASE 0x90000000 /* IRQ, Test chip */ |
91 | -#define CNS3XXX_TC11MP_SCU_BASE_VIRT 0xFF000000 |
92 | +#define CNS3XXX_TC11MP_SCU_BASE_VIRT 0xFB004000 |
93 | |
94 | #define CNS3XXX_TC11MP_GIC_CPU_BASE 0x90000100 /* Test chip interrupt controller CPU interface */ |
95 | -#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT 0xFF000100 |
96 | +#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x100) |
97 | |
98 | #define CNS3XXX_TC11MP_TWD_BASE 0x90000600 |
99 | -#define CNS3XXX_TC11MP_TWD_BASE_VIRT 0xFF000600 |
100 | +#define CNS3XXX_TC11MP_TWD_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x600) |
101 | |
102 | #define CNS3XXX_TC11MP_GIC_DIST_BASE 0x90001000 /* Test chip interrupt controller distributor */ |
103 | -#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT 0xFF001000 |
104 | +#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x1000) |
105 | |
106 | #define CNS3XXX_TC11MP_L220_BASE 0x92002000 /* L220 registers */ |
107 | #define CNS3XXX_TC11MP_L220_BASE_VIRT 0xFF002000 |
108 | diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h |
109 | index fa36fb8..122da24 100644 |
110 | --- a/arch/arm/mach-imx/common.h |
111 | +++ b/arch/arm/mach-imx/common.h |
112 | @@ -116,6 +116,8 @@ void tzic_handle_irq(struct pt_regs *); |
113 | |
114 | extern void imx_enable_cpu(int cpu, bool enable); |
115 | extern void imx_set_cpu_jump(int cpu, void *jump_addr); |
116 | +extern u32 imx_get_cpu_arg(int cpu); |
117 | +extern void imx_set_cpu_arg(int cpu, u32 arg); |
118 | #ifdef CONFIG_DEBUG_LL |
119 | extern void imx_lluart_map_io(void); |
120 | #else |
121 | diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c |
122 | index 7bc5fe1..361a253 100644 |
123 | --- a/arch/arm/mach-imx/hotplug.c |
124 | +++ b/arch/arm/mach-imx/hotplug.c |
125 | @@ -46,11 +46,23 @@ static inline void cpu_enter_lowpower(void) |
126 | void imx_cpu_die(unsigned int cpu) |
127 | { |
128 | cpu_enter_lowpower(); |
129 | + /* |
130 | + * We use the cpu jumping argument register to sync with |
131 | + * imx_cpu_kill() which is running on cpu0 and waiting for |
132 | + * the register being cleared to kill the cpu. |
133 | + */ |
134 | + imx_set_cpu_arg(cpu, ~0); |
135 | cpu_do_idle(); |
136 | } |
137 | |
138 | int imx_cpu_kill(unsigned int cpu) |
139 | { |
140 | + unsigned long timeout = jiffies + msecs_to_jiffies(50); |
141 | + |
142 | + while (imx_get_cpu_arg(cpu) == 0) |
143 | + if (time_after(jiffies, timeout)) |
144 | + return 0; |
145 | imx_enable_cpu(cpu, false); |
146 | + imx_set_cpu_arg(cpu, 0); |
147 | return 1; |
148 | } |
149 | diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c |
150 | index e15f155..09a742f 100644 |
151 | --- a/arch/arm/mach-imx/src.c |
152 | +++ b/arch/arm/mach-imx/src.c |
153 | @@ -43,6 +43,18 @@ void imx_set_cpu_jump(int cpu, void *jump_addr) |
154 | src_base + SRC_GPR1 + cpu * 8); |
155 | } |
156 | |
157 | +u32 imx_get_cpu_arg(int cpu) |
158 | +{ |
159 | + cpu = cpu_logical_map(cpu); |
160 | + return readl_relaxed(src_base + SRC_GPR1 + cpu * 8 + 4); |
161 | +} |
162 | + |
163 | +void imx_set_cpu_arg(int cpu, u32 arg) |
164 | +{ |
165 | + cpu = cpu_logical_map(cpu); |
166 | + writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4); |
167 | +} |
168 | + |
169 | void imx_src_prepare_restart(void) |
170 | { |
171 | u32 val; |
172 | diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h |
173 | index 948bcaa..b9adf69 100644 |
174 | --- a/arch/arm/mach-omap2/common.h |
175 | +++ b/arch/arm/mach-omap2/common.h |
176 | @@ -286,5 +286,8 @@ extern void omap_reserve(void); |
177 | struct omap_hwmod; |
178 | extern int omap_dss_reset(struct omap_hwmod *); |
179 | |
180 | +/* SoC specific clock initializer */ |
181 | +extern int (*omap_clk_init)(void); |
182 | + |
183 | #endif /* __ASSEMBLER__ */ |
184 | #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ |
185 | diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c |
186 | index 2c3fdd6..5c445ca 100644 |
187 | --- a/arch/arm/mach-omap2/io.c |
188 | +++ b/arch/arm/mach-omap2/io.c |
189 | @@ -55,6 +55,12 @@ |
190 | #include "prm44xx.h" |
191 | |
192 | /* |
193 | + * omap_clk_init: points to a function that does the SoC-specific |
194 | + * clock initializations |
195 | + */ |
196 | +int (*omap_clk_init)(void); |
197 | + |
198 | +/* |
199 | * The machine specific code may provide the extra mapping besides the |
200 | * default mapping provided here. |
201 | */ |
202 | @@ -397,7 +403,7 @@ void __init omap2420_init_early(void) |
203 | omap242x_clockdomains_init(); |
204 | omap2420_hwmod_init(); |
205 | omap_hwmod_init_postsetup(); |
206 | - omap2420_clk_init(); |
207 | + omap_clk_init = omap2420_clk_init; |
208 | } |
209 | |
210 | void __init omap2420_init_late(void) |
211 | @@ -427,7 +433,7 @@ void __init omap2430_init_early(void) |
212 | omap243x_clockdomains_init(); |
213 | omap2430_hwmod_init(); |
214 | omap_hwmod_init_postsetup(); |
215 | - omap2430_clk_init(); |
216 | + omap_clk_init = omap2430_clk_init; |
217 | } |
218 | |
219 | void __init omap2430_init_late(void) |
220 | @@ -462,7 +468,7 @@ void __init omap3_init_early(void) |
221 | omap3xxx_clockdomains_init(); |
222 | omap3xxx_hwmod_init(); |
223 | omap_hwmod_init_postsetup(); |
224 | - omap3xxx_clk_init(); |
225 | + omap_clk_init = omap3xxx_clk_init; |
226 | } |
227 | |
228 | void __init omap3430_init_early(void) |
229 | @@ -500,7 +506,7 @@ void __init ti81xx_init_early(void) |
230 | omap3xxx_clockdomains_init(); |
231 | omap3xxx_hwmod_init(); |
232 | omap_hwmod_init_postsetup(); |
233 | - omap3xxx_clk_init(); |
234 | + omap_clk_init = omap3xxx_clk_init; |
235 | } |
236 | |
237 | void __init omap3_init_late(void) |
238 | @@ -568,7 +574,7 @@ void __init am33xx_init_early(void) |
239 | am33xx_clockdomains_init(); |
240 | am33xx_hwmod_init(); |
241 | omap_hwmod_init_postsetup(); |
242 | - am33xx_clk_init(); |
243 | + omap_clk_init = am33xx_clk_init; |
244 | } |
245 | #endif |
246 | |
247 | @@ -593,7 +599,7 @@ void __init omap4430_init_early(void) |
248 | omap44xx_clockdomains_init(); |
249 | omap44xx_hwmod_init(); |
250 | omap_hwmod_init_postsetup(); |
251 | - omap4xxx_clk_init(); |
252 | + omap_clk_init = omap4xxx_clk_init; |
253 | } |
254 | |
255 | void __init omap4430_init_late(void) |
256 | diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c |
257 | index b8ad6e6..559c87b 100644 |
258 | --- a/arch/arm/mach-omap2/timer.c |
259 | +++ b/arch/arm/mach-omap2/timer.c |
260 | @@ -554,6 +554,8 @@ static inline void __init realtime_counter_init(void) |
261 | clksrc_nr, clksrc_src) \ |
262 | static void __init omap##name##_gptimer_timer_init(void) \ |
263 | { \ |
264 | + if (omap_clk_init) \ |
265 | + omap_clk_init(); \ |
266 | omap_dmtimer_init(); \ |
267 | omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ |
268 | omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src); \ |
269 | @@ -563,6 +565,8 @@ static void __init omap##name##_gptimer_timer_init(void) \ |
270 | clksrc_nr, clksrc_src) \ |
271 | static void __init omap##name##_sync32k_timer_init(void) \ |
272 | { \ |
273 | + if (omap_clk_init) \ |
274 | + omap_clk_init(); \ |
275 | omap_dmtimer_init(); \ |
276 | omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ |
277 | /* Enable the use of clocksource="gp_timer" kernel parameter */ \ |
278 | diff --git a/arch/avr32/include/asm/signal.h b/arch/avr32/include/asm/signal.h |
279 | index 9326d18..b65e61a 100644 |
280 | --- a/arch/avr32/include/asm/signal.h |
281 | +++ b/arch/avr32/include/asm/signal.h |
282 | @@ -29,6 +29,7 @@ struct sigaction { |
283 | __sigrestore_t sa_restorer; |
284 | sigset_t sa_mask; /* mask last for extensibility */ |
285 | }; |
286 | +#define __ARCH_HAS_SA_RESTORER |
287 | |
288 | struct k_sigaction { |
289 | struct sigaction sa; |
290 | diff --git a/arch/cris/include/asm/signal.h b/arch/cris/include/asm/signal.h |
291 | index c0cb1fd..a7e267c 100644 |
292 | --- a/arch/cris/include/asm/signal.h |
293 | +++ b/arch/cris/include/asm/signal.h |
294 | @@ -29,6 +29,7 @@ struct sigaction { |
295 | void (*sa_restorer)(void); |
296 | sigset_t sa_mask; /* mask last for extensibility */ |
297 | }; |
298 | +#define __ARCH_HAS_SA_RESTORER |
299 | |
300 | struct k_sigaction { |
301 | struct sigaction sa; |
302 | diff --git a/arch/h8300/include/asm/signal.h b/arch/h8300/include/asm/signal.h |
303 | index 66c81c6..4bf76ac 100644 |
304 | --- a/arch/h8300/include/asm/signal.h |
305 | +++ b/arch/h8300/include/asm/signal.h |
306 | @@ -29,6 +29,7 @@ struct sigaction { |
307 | void (*sa_restorer)(void); |
308 | sigset_t sa_mask; /* mask last for extensibility */ |
309 | }; |
310 | +#define __ARCH_HAS_SA_RESTORER |
311 | |
312 | struct k_sigaction { |
313 | struct sigaction sa; |
314 | diff --git a/arch/m32r/include/asm/signal.h b/arch/m32r/include/asm/signal.h |
315 | index a5ba4a2..04ccbcd 100644 |
316 | --- a/arch/m32r/include/asm/signal.h |
317 | +++ b/arch/m32r/include/asm/signal.h |
318 | @@ -22,6 +22,7 @@ struct sigaction { |
319 | __sigrestore_t sa_restorer; |
320 | sigset_t sa_mask; /* mask last for extensibility */ |
321 | }; |
322 | +#define __ARCH_HAS_SA_RESTORER |
323 | |
324 | struct k_sigaction { |
325 | struct sigaction sa; |
326 | diff --git a/arch/m68k/include/asm/signal.h b/arch/m68k/include/asm/signal.h |
327 | index 9c8c46b..60370da 100644 |
328 | --- a/arch/m68k/include/asm/signal.h |
329 | +++ b/arch/m68k/include/asm/signal.h |
330 | @@ -29,6 +29,7 @@ struct sigaction { |
331 | __sigrestore_t sa_restorer; |
332 | sigset_t sa_mask; /* mask last for extensibility */ |
333 | }; |
334 | +#define __ARCH_HAS_SA_RESTORER |
335 | |
336 | struct k_sigaction { |
337 | struct sigaction sa; |
338 | diff --git a/arch/mn10300/include/asm/signal.h b/arch/mn10300/include/asm/signal.h |
339 | index d280e97..d673860 100644 |
340 | --- a/arch/mn10300/include/asm/signal.h |
341 | +++ b/arch/mn10300/include/asm/signal.h |
342 | @@ -39,6 +39,7 @@ struct sigaction { |
343 | __sigrestore_t sa_restorer; |
344 | sigset_t sa_mask; /* mask last for extensibility */ |
345 | }; |
346 | +#define __ARCH_HAS_SA_RESTORER |
347 | |
348 | struct k_sigaction { |
349 | struct sigaction sa; |
350 | diff --git a/arch/powerpc/include/asm/signal.h b/arch/powerpc/include/asm/signal.h |
351 | index a101637..fbe66c4 100644 |
352 | --- a/arch/powerpc/include/asm/signal.h |
353 | +++ b/arch/powerpc/include/asm/signal.h |
354 | @@ -1,6 +1,7 @@ |
355 | #ifndef _ASM_POWERPC_SIGNAL_H |
356 | #define _ASM_POWERPC_SIGNAL_H |
357 | |
358 | +#define __ARCH_HAS_SA_RESTORER |
359 | #include <uapi/asm/signal.h> |
360 | |
361 | #endif /* _ASM_POWERPC_SIGNAL_H */ |
362 | diff --git a/arch/s390/include/asm/signal.h b/arch/s390/include/asm/signal.h |
363 | index db7ddfa..639f569 100644 |
364 | --- a/arch/s390/include/asm/signal.h |
365 | +++ b/arch/s390/include/asm/signal.h |
366 | @@ -34,6 +34,7 @@ struct sigaction { |
367 | void (*sa_restorer)(void); |
368 | sigset_t sa_mask; /* mask last for extensibility */ |
369 | }; |
370 | +#define __ARCH_HAS_SA_RESTORER |
371 | |
372 | struct k_sigaction { |
373 | struct sigaction sa; |
374 | diff --git a/arch/sparc/include/asm/signal.h b/arch/sparc/include/asm/signal.h |
375 | index 77b8585..2f0df05 100644 |
376 | --- a/arch/sparc/include/asm/signal.h |
377 | +++ b/arch/sparc/include/asm/signal.h |
378 | @@ -26,5 +26,7 @@ struct k_sigaction { |
379 | void __user *ka_restorer; |
380 | }; |
381 | |
382 | +#define __ARCH_HAS_SA_RESTORER |
383 | + |
384 | #endif /* !(__ASSEMBLY__) */ |
385 | #endif /* !(__SPARC_SIGNAL_H) */ |
386 | diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c |
387 | index d1e15f7..7a5aa1a 100644 |
388 | --- a/arch/tile/kernel/setup.c |
389 | +++ b/arch/tile/kernel/setup.c |
390 | @@ -1004,15 +1004,8 @@ void __cpuinit setup_cpu(int boot) |
391 | |
392 | #ifdef CONFIG_BLK_DEV_INITRD |
393 | |
394 | -/* |
395 | - * Note that the kernel can potentially support other compression |
396 | - * techniques than gz, though we don't do so by default. If we ever |
397 | - * decide to do so we can either look for other filename extensions, |
398 | - * or just allow a file with this name to be compressed with an |
399 | - * arbitrary compressor (somewhat counterintuitively). |
400 | - */ |
401 | static int __initdata set_initramfs_file; |
402 | -static char __initdata initramfs_file[128] = "initramfs.cpio.gz"; |
403 | +static char __initdata initramfs_file[128] = "initramfs"; |
404 | |
405 | static int __init setup_initramfs_file(char *str) |
406 | { |
407 | @@ -1026,9 +1019,9 @@ static int __init setup_initramfs_file(char *str) |
408 | early_param("initramfs_file", setup_initramfs_file); |
409 | |
410 | /* |
411 | - * We look for an "initramfs.cpio.gz" file in the hvfs. |
412 | - * If there is one, we allocate some memory for it and it will be |
413 | - * unpacked to the initramfs. |
414 | + * We look for a file called "initramfs" in the hvfs. If there is one, we |
415 | + * allocate some memory for it and it will be unpacked to the initramfs. |
416 | + * If it's compressed, the initd code will uncompress it first. |
417 | */ |
418 | static void __init load_hv_initrd(void) |
419 | { |
420 | @@ -1038,10 +1031,16 @@ static void __init load_hv_initrd(void) |
421 | |
422 | fd = hv_fs_findfile((HV_VirtAddr) initramfs_file); |
423 | if (fd == HV_ENOENT) { |
424 | - if (set_initramfs_file) |
425 | + if (set_initramfs_file) { |
426 | pr_warning("No such hvfs initramfs file '%s'\n", |
427 | initramfs_file); |
428 | - return; |
429 | + return; |
430 | + } else { |
431 | + /* Try old backwards-compatible name. */ |
432 | + fd = hv_fs_findfile((HV_VirtAddr)"initramfs.cpio.gz"); |
433 | + if (fd == HV_ENOENT) |
434 | + return; |
435 | + } |
436 | } |
437 | BUG_ON(fd < 0); |
438 | stat = hv_fs_fstat(fd); |
439 | diff --git a/arch/x86/include/asm/signal.h b/arch/x86/include/asm/signal.h |
440 | index 216bf36..111d272 100644 |
441 | --- a/arch/x86/include/asm/signal.h |
442 | +++ b/arch/x86/include/asm/signal.h |
443 | @@ -31,6 +31,9 @@ typedef sigset_t compat_sigset_t; |
444 | #include <uapi/asm/signal.h> |
445 | #ifndef __ASSEMBLY__ |
446 | extern void do_notify_resume(struct pt_regs *, void *, __u32); |
447 | + |
448 | +#define __ARCH_HAS_SA_RESTORER |
449 | + |
450 | #ifdef __i386__ |
451 | struct old_sigaction { |
452 | __sighandler_t sa_handler; |
453 | diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h |
454 | index c20d1ce..e709884 100644 |
455 | --- a/arch/x86/include/asm/xen/hypercall.h |
456 | +++ b/arch/x86/include/asm/xen/hypercall.h |
457 | @@ -382,14 +382,14 @@ HYPERVISOR_console_io(int cmd, int count, char *str) |
458 | return _hypercall3(int, console_io, cmd, count, str); |
459 | } |
460 | |
461 | -extern int __must_check HYPERVISOR_physdev_op_compat(int, void *); |
462 | +extern int __must_check xen_physdev_op_compat(int, void *); |
463 | |
464 | static inline int |
465 | HYPERVISOR_physdev_op(int cmd, void *arg) |
466 | { |
467 | int rc = _hypercall2(int, physdev_op, cmd, arg); |
468 | if (unlikely(rc == -ENOSYS)) |
469 | - rc = HYPERVISOR_physdev_op_compat(cmd, arg); |
470 | + rc = xen_physdev_op_compat(cmd, arg); |
471 | return rc; |
472 | } |
473 | |
474 | diff --git a/arch/xtensa/include/asm/signal.h b/arch/xtensa/include/asm/signal.h |
475 | index 6f586bd..83e23f4 100644 |
476 | --- a/arch/xtensa/include/asm/signal.h |
477 | +++ b/arch/xtensa/include/asm/signal.h |
478 | @@ -21,6 +21,7 @@ struct sigaction { |
479 | void (*sa_restorer)(void); |
480 | sigset_t sa_mask; /* mask last for extensibility */ |
481 | }; |
482 | +#define __ARCH_HAS_SA_RESTORER |
483 | |
484 | struct k_sigaction { |
485 | struct sigaction sa; |
486 | diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c |
487 | index 25ef5c0..92b6d7c 100644 |
488 | --- a/drivers/block/aoe/aoecmd.c |
489 | +++ b/drivers/block/aoe/aoecmd.c |
490 | @@ -51,8 +51,9 @@ new_skb(ulong len) |
491 | { |
492 | struct sk_buff *skb; |
493 | |
494 | - skb = alloc_skb(len, GFP_ATOMIC); |
495 | + skb = alloc_skb(len + MAX_HEADER, GFP_ATOMIC); |
496 | if (skb) { |
497 | + skb_reserve(skb, MAX_HEADER); |
498 | skb_reset_mac_header(skb); |
499 | skb_reset_network_header(skb); |
500 | skb->protocol = __constant_htons(ETH_P_AOE); |
501 | diff --git a/drivers/block/loop.c b/drivers/block/loop.c |
502 | index 8bc6d39..f74f2c0 100644 |
503 | --- a/drivers/block/loop.c |
504 | +++ b/drivers/block/loop.c |
505 | @@ -917,6 +917,11 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, |
506 | lo->lo_flags |= LO_FLAGS_PARTSCAN; |
507 | if (lo->lo_flags & LO_FLAGS_PARTSCAN) |
508 | ioctl_by_bdev(bdev, BLKRRPART, 0); |
509 | + |
510 | + /* Grab the block_device to prevent its destruction after we |
511 | + * put /dev/loopXX inode. Later in loop_clr_fd() we bdput(bdev). |
512 | + */ |
513 | + bdgrab(bdev); |
514 | return 0; |
515 | |
516 | out_clr: |
517 | @@ -1026,8 +1031,10 @@ static int loop_clr_fd(struct loop_device *lo) |
518 | memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); |
519 | memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); |
520 | memset(lo->lo_file_name, 0, LO_NAME_SIZE); |
521 | - if (bdev) |
522 | + if (bdev) { |
523 | + bdput(bdev); |
524 | invalidate_bdev(bdev); |
525 | + } |
526 | set_capacity(lo->lo_disk, 0); |
527 | loop_sysfs_exit(lo); |
528 | if (bdev) { |
529 | diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c |
530 | index e34a7b4..ef6d9be 100644 |
531 | --- a/drivers/block/xen-blkback/blkback.c |
532 | +++ b/drivers/block/xen-blkback/blkback.c |
533 | @@ -679,6 +679,16 @@ static int dispatch_discard_io(struct xen_blkif *blkif, |
534 | return err; |
535 | } |
536 | |
537 | +static int dispatch_other_io(struct xen_blkif *blkif, |
538 | + struct blkif_request *req, |
539 | + struct pending_req *pending_req) |
540 | +{ |
541 | + free_req(pending_req); |
542 | + make_response(blkif, req->u.other.id, req->operation, |
543 | + BLKIF_RSP_EOPNOTSUPP); |
544 | + return -EIO; |
545 | +} |
546 | + |
547 | static void xen_blk_drain_io(struct xen_blkif *blkif) |
548 | { |
549 | atomic_set(&blkif->drain, 1); |
550 | @@ -800,17 +810,30 @@ __do_block_io_op(struct xen_blkif *blkif) |
551 | |
552 | /* Apply all sanity checks to /private copy/ of request. */ |
553 | barrier(); |
554 | - if (unlikely(req.operation == BLKIF_OP_DISCARD)) { |
555 | + |
556 | + switch (req.operation) { |
557 | + case BLKIF_OP_READ: |
558 | + case BLKIF_OP_WRITE: |
559 | + case BLKIF_OP_WRITE_BARRIER: |
560 | + case BLKIF_OP_FLUSH_DISKCACHE: |
561 | + if (dispatch_rw_block_io(blkif, &req, pending_req)) |
562 | + goto done; |
563 | + break; |
564 | + case BLKIF_OP_DISCARD: |
565 | free_req(pending_req); |
566 | if (dispatch_discard_io(blkif, &req)) |
567 | - break; |
568 | - } else if (dispatch_rw_block_io(blkif, &req, pending_req)) |
569 | + goto done; |
570 | break; |
571 | + default: |
572 | + if (dispatch_other_io(blkif, &req, pending_req)) |
573 | + goto done; |
574 | + break; |
575 | + } |
576 | |
577 | /* Yield point for this unbounded loop. */ |
578 | cond_resched(); |
579 | } |
580 | - |
581 | +done: |
582 | return more_to_do; |
583 | } |
584 | |
585 | @@ -978,13 +1001,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, |
586 | bio->bi_end_io = end_block_io_op; |
587 | } |
588 | |
589 | - /* |
590 | - * We set it one so that the last submit_bio does not have to call |
591 | - * atomic_inc. |
592 | - */ |
593 | atomic_set(&pending_req->pendcnt, nbio); |
594 | - |
595 | - /* Get a reference count for the disk queue and start sending I/O */ |
596 | blk_start_plug(&plug); |
597 | |
598 | for (i = 0; i < nbio; i++) |
599 | @@ -1012,6 +1029,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, |
600 | fail_put_bio: |
601 | for (i = 0; i < nbio; i++) |
602 | bio_put(biolist[i]); |
603 | + atomic_set(&pending_req->pendcnt, 1); |
604 | __end_block_io_op(pending_req, -EINVAL); |
605 | msleep(1); /* back off a bit */ |
606 | return -EIO; |
607 | diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h |
608 | index 6072390..195278a 100644 |
609 | --- a/drivers/block/xen-blkback/common.h |
610 | +++ b/drivers/block/xen-blkback/common.h |
611 | @@ -77,11 +77,18 @@ struct blkif_x86_32_request_discard { |
612 | uint64_t nr_sectors; |
613 | } __attribute__((__packed__)); |
614 | |
615 | +struct blkif_x86_32_request_other { |
616 | + uint8_t _pad1; |
617 | + blkif_vdev_t _pad2; |
618 | + uint64_t id; /* private guest value, echoed in resp */ |
619 | +} __attribute__((__packed__)); |
620 | + |
621 | struct blkif_x86_32_request { |
622 | uint8_t operation; /* BLKIF_OP_??? */ |
623 | union { |
624 | struct blkif_x86_32_request_rw rw; |
625 | struct blkif_x86_32_request_discard discard; |
626 | + struct blkif_x86_32_request_other other; |
627 | } u; |
628 | } __attribute__((__packed__)); |
629 | |
630 | @@ -113,11 +120,19 @@ struct blkif_x86_64_request_discard { |
631 | uint64_t nr_sectors; |
632 | } __attribute__((__packed__)); |
633 | |
634 | +struct blkif_x86_64_request_other { |
635 | + uint8_t _pad1; |
636 | + blkif_vdev_t _pad2; |
637 | + uint32_t _pad3; /* offsetof(blkif_..,u.discard.id)==8 */ |
638 | + uint64_t id; /* private guest value, echoed in resp */ |
639 | +} __attribute__((__packed__)); |
640 | + |
641 | struct blkif_x86_64_request { |
642 | uint8_t operation; /* BLKIF_OP_??? */ |
643 | union { |
644 | struct blkif_x86_64_request_rw rw; |
645 | struct blkif_x86_64_request_discard discard; |
646 | + struct blkif_x86_64_request_other other; |
647 | } u; |
648 | } __attribute__((__packed__)); |
649 | |
650 | @@ -278,6 +293,11 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst, |
651 | dst->u.discard.nr_sectors = src->u.discard.nr_sectors; |
652 | break; |
653 | default: |
654 | + /* |
655 | + * Don't know how to translate this op. Only get the |
656 | + * ID so failure can be reported to the frontend. |
657 | + */ |
658 | + dst->u.other.id = src->u.other.id; |
659 | break; |
660 | } |
661 | } |
662 | @@ -309,6 +329,11 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst, |
663 | dst->u.discard.nr_sectors = src->u.discard.nr_sectors; |
664 | break; |
665 | default: |
666 | + /* |
667 | + * Don't know how to translate this op. Only get the |
668 | + * ID so failure can be reported to the frontend. |
669 | + */ |
670 | + dst->u.other.id = src->u.other.id; |
671 | break; |
672 | } |
673 | } |
674 | diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c |
675 | index c3dae2e..2e39eaf 100644 |
676 | --- a/drivers/block/xen-blkfront.c |
677 | +++ b/drivers/block/xen-blkfront.c |
678 | @@ -44,7 +44,7 @@ |
679 | #include <linux/mutex.h> |
680 | #include <linux/scatterlist.h> |
681 | #include <linux/bitmap.h> |
682 | -#include <linux/llist.h> |
683 | +#include <linux/list.h> |
684 | |
685 | #include <xen/xen.h> |
686 | #include <xen/xenbus.h> |
687 | @@ -68,7 +68,7 @@ enum blkif_state { |
688 | struct grant { |
689 | grant_ref_t gref; |
690 | unsigned long pfn; |
691 | - struct llist_node node; |
692 | + struct list_head node; |
693 | }; |
694 | |
695 | struct blk_shadow { |
696 | @@ -105,7 +105,7 @@ struct blkfront_info |
697 | struct work_struct work; |
698 | struct gnttab_free_callback callback; |
699 | struct blk_shadow shadow[BLK_RING_SIZE]; |
700 | - struct llist_head persistent_gnts; |
701 | + struct list_head persistent_gnts; |
702 | unsigned int persistent_gnts_c; |
703 | unsigned long shadow_free; |
704 | unsigned int feature_flush; |
705 | @@ -371,10 +371,11 @@ static int blkif_queue_request(struct request *req) |
706 | lsect = fsect + (sg->length >> 9) - 1; |
707 | |
708 | if (info->persistent_gnts_c) { |
709 | - BUG_ON(llist_empty(&info->persistent_gnts)); |
710 | - gnt_list_entry = llist_entry( |
711 | - llist_del_first(&info->persistent_gnts), |
712 | - struct grant, node); |
713 | + BUG_ON(list_empty(&info->persistent_gnts)); |
714 | + gnt_list_entry = list_first_entry( |
715 | + &info->persistent_gnts, |
716 | + struct grant, node); |
717 | + list_del(&gnt_list_entry->node); |
718 | |
719 | ref = gnt_list_entry->gref; |
720 | buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn); |
721 | @@ -790,9 +791,8 @@ static void blkif_restart_queue(struct work_struct *work) |
722 | |
723 | static void blkif_free(struct blkfront_info *info, int suspend) |
724 | { |
725 | - struct llist_node *all_gnts; |
726 | - struct grant *persistent_gnt, *tmp; |
727 | - struct llist_node *n; |
728 | + struct grant *persistent_gnt; |
729 | + struct grant *n; |
730 | |
731 | /* Prevent new requests being issued until we fix things up. */ |
732 | spin_lock_irq(&info->io_lock); |
733 | @@ -804,20 +804,15 @@ static void blkif_free(struct blkfront_info *info, int suspend) |
734 | |
735 | /* Remove all persistent grants */ |
736 | if (info->persistent_gnts_c) { |
737 | - all_gnts = llist_del_all(&info->persistent_gnts); |
738 | - persistent_gnt = llist_entry(all_gnts, typeof(*(persistent_gnt)), node); |
739 | - while (persistent_gnt) { |
740 | + list_for_each_entry_safe(persistent_gnt, n, |
741 | + &info->persistent_gnts, node) { |
742 | + list_del(&persistent_gnt->node); |
743 | gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL); |
744 | __free_page(pfn_to_page(persistent_gnt->pfn)); |
745 | - tmp = persistent_gnt; |
746 | - n = persistent_gnt->node.next; |
747 | - if (n) |
748 | - persistent_gnt = llist_entry(n, typeof(*(persistent_gnt)), node); |
749 | - else |
750 | - persistent_gnt = NULL; |
751 | - kfree(tmp); |
752 | + kfree(persistent_gnt); |
753 | + info->persistent_gnts_c--; |
754 | } |
755 | - info->persistent_gnts_c = 0; |
756 | + BUG_ON(info->persistent_gnts_c != 0); |
757 | } |
758 | |
759 | /* No more gnttab callback work. */ |
760 | @@ -875,7 +870,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info, |
761 | } |
762 | /* Add the persistent grant into the list of free grants */ |
763 | for (i = 0; i < s->req.u.rw.nr_segments; i++) { |
764 | - llist_add(&s->grants_used[i]->node, &info->persistent_gnts); |
765 | + list_add(&s->grants_used[i]->node, &info->persistent_gnts); |
766 | info->persistent_gnts_c++; |
767 | } |
768 | } |
769 | @@ -1171,7 +1166,7 @@ static int blkfront_probe(struct xenbus_device *dev, |
770 | spin_lock_init(&info->io_lock); |
771 | info->xbdev = dev; |
772 | info->vdevice = vdevice; |
773 | - init_llist_head(&info->persistent_gnts); |
774 | + INIT_LIST_HEAD(&info->persistent_gnts); |
775 | info->persistent_gnts_c = 0; |
776 | info->connected = BLKIF_STATE_DISCONNECTED; |
777 | INIT_WORK(&info->work, blkif_restart_queue); |
778 | diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c |
779 | index 33c9a44..1c0929b 100644 |
780 | --- a/drivers/bluetooth/ath3k.c |
781 | +++ b/drivers/bluetooth/ath3k.c |
782 | @@ -73,8 +73,10 @@ static struct usb_device_id ath3k_table[] = { |
783 | { USB_DEVICE(0x03F0, 0x311D) }, |
784 | |
785 | /* Atheros AR3012 with sflash firmware*/ |
786 | + { USB_DEVICE(0x0CF3, 0x0036) }, |
787 | { USB_DEVICE(0x0CF3, 0x3004) }, |
788 | { USB_DEVICE(0x0CF3, 0x311D) }, |
789 | + { USB_DEVICE(0x0CF3, 0x817a) }, |
790 | { USB_DEVICE(0x13d3, 0x3375) }, |
791 | { USB_DEVICE(0x04CA, 0x3005) }, |
792 | { USB_DEVICE(0x04CA, 0x3006) }, |
793 | @@ -105,8 +107,10 @@ MODULE_DEVICE_TABLE(usb, ath3k_table); |
794 | static struct usb_device_id ath3k_blist_tbl[] = { |
795 | |
796 | /* Atheros AR3012 with sflash firmware*/ |
797 | + { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 }, |
798 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, |
799 | { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, |
800 | + { USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 }, |
801 | { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, |
802 | { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, |
803 | { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, |
804 | diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c |
805 | index 7e351e3..568e703 100644 |
806 | --- a/drivers/bluetooth/btusb.c |
807 | +++ b/drivers/bluetooth/btusb.c |
808 | @@ -131,8 +131,10 @@ static struct usb_device_id blacklist_table[] = { |
809 | { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, |
810 | |
811 | /* Atheros 3012 with sflash firmware */ |
812 | + { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, |
813 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, |
814 | { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, |
815 | + { USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 }, |
816 | { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, |
817 | { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, |
818 | { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, |
819 | diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c |
820 | index ee4dbea..a4b7aa0 100644 |
821 | --- a/drivers/char/virtio_console.c |
822 | +++ b/drivers/char/virtio_console.c |
823 | @@ -152,7 +152,8 @@ struct ports_device { |
824 | spinlock_t ports_lock; |
825 | |
826 | /* To protect the vq operations for the control channel */ |
827 | - spinlock_t cvq_lock; |
828 | + spinlock_t c_ivq_lock; |
829 | + spinlock_t c_ovq_lock; |
830 | |
831 | /* The current config space is stored here */ |
832 | struct virtio_console_config config; |
833 | @@ -575,11 +576,14 @@ static ssize_t __send_control_msg(struct ports_device *portdev, u32 port_id, |
834 | vq = portdev->c_ovq; |
835 | |
836 | sg_init_one(sg, &cpkt, sizeof(cpkt)); |
837 | + |
838 | + spin_lock(&portdev->c_ovq_lock); |
839 | if (virtqueue_add_buf(vq, sg, 1, 0, &cpkt, GFP_ATOMIC) == 0) { |
840 | virtqueue_kick(vq); |
841 | while (!virtqueue_get_buf(vq, &len)) |
842 | cpu_relax(); |
843 | } |
844 | + spin_unlock(&portdev->c_ovq_lock); |
845 | return 0; |
846 | } |
847 | |
848 | @@ -1715,23 +1719,23 @@ static void control_work_handler(struct work_struct *work) |
849 | portdev = container_of(work, struct ports_device, control_work); |
850 | vq = portdev->c_ivq; |
851 | |
852 | - spin_lock(&portdev->cvq_lock); |
853 | + spin_lock(&portdev->c_ivq_lock); |
854 | while ((buf = virtqueue_get_buf(vq, &len))) { |
855 | - spin_unlock(&portdev->cvq_lock); |
856 | + spin_unlock(&portdev->c_ivq_lock); |
857 | |
858 | buf->len = len; |
859 | buf->offset = 0; |
860 | |
861 | handle_control_message(portdev, buf); |
862 | |
863 | - spin_lock(&portdev->cvq_lock); |
864 | + spin_lock(&portdev->c_ivq_lock); |
865 | if (add_inbuf(portdev->c_ivq, buf) < 0) { |
866 | dev_warn(&portdev->vdev->dev, |
867 | "Error adding buffer to queue\n"); |
868 | free_buf(buf, false); |
869 | } |
870 | } |
871 | - spin_unlock(&portdev->cvq_lock); |
872 | + spin_unlock(&portdev->c_ivq_lock); |
873 | } |
874 | |
875 | static void out_intr(struct virtqueue *vq) |
876 | @@ -1996,10 +2000,12 @@ static int virtcons_probe(struct virtio_device *vdev) |
877 | if (multiport) { |
878 | unsigned int nr_added_bufs; |
879 | |
880 | - spin_lock_init(&portdev->cvq_lock); |
881 | + spin_lock_init(&portdev->c_ivq_lock); |
882 | + spin_lock_init(&portdev->c_ovq_lock); |
883 | INIT_WORK(&portdev->control_work, &control_work_handler); |
884 | |
885 | - nr_added_bufs = fill_queue(portdev->c_ivq, &portdev->cvq_lock); |
886 | + nr_added_bufs = fill_queue(portdev->c_ivq, |
887 | + &portdev->c_ivq_lock); |
888 | if (!nr_added_bufs) { |
889 | dev_err(&vdev->dev, |
890 | "Error allocating buffers for control queue\n"); |
891 | @@ -2150,7 +2156,7 @@ static int virtcons_restore(struct virtio_device *vdev) |
892 | return ret; |
893 | |
894 | if (use_multiport(portdev)) |
895 | - fill_queue(portdev->c_ivq, &portdev->cvq_lock); |
896 | + fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); |
897 | |
898 | list_for_each_entry(port, &portdev->ports, list) { |
899 | port->in_vq = portdev->in_vqs[port->id]; |
900 | diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c |
901 | index b2a0a07..cf268b1 100644 |
902 | --- a/drivers/crypto/caam/caamalg.c |
903 | +++ b/drivers/crypto/caam/caamalg.c |
904 | @@ -1650,11 +1650,7 @@ struct caam_alg_template { |
905 | }; |
906 | |
907 | static struct caam_alg_template driver_algs[] = { |
908 | - /* |
909 | - * single-pass ipsec_esp descriptor |
910 | - * authencesn(*,*) is also registered, although not present |
911 | - * explicitly here. |
912 | - */ |
913 | + /* single-pass ipsec_esp descriptor */ |
914 | { |
915 | .name = "authenc(hmac(md5),cbc(aes))", |
916 | .driver_name = "authenc-hmac-md5-cbc-aes-caam", |
917 | @@ -2217,9 +2213,7 @@ static int __init caam_algapi_init(void) |
918 | for (i = 0; i < ARRAY_SIZE(driver_algs); i++) { |
919 | /* TODO: check if h/w supports alg */ |
920 | struct caam_crypto_alg *t_alg; |
921 | - bool done = false; |
922 | |
923 | -authencesn: |
924 | t_alg = caam_alg_alloc(ctrldev, &driver_algs[i]); |
925 | if (IS_ERR(t_alg)) { |
926 | err = PTR_ERR(t_alg); |
927 | @@ -2233,25 +2227,8 @@ authencesn: |
928 | dev_warn(ctrldev, "%s alg registration failed\n", |
929 | t_alg->crypto_alg.cra_driver_name); |
930 | kfree(t_alg); |
931 | - } else { |
932 | + } else |
933 | list_add_tail(&t_alg->entry, &priv->alg_list); |
934 | - if (driver_algs[i].type == CRYPTO_ALG_TYPE_AEAD && |
935 | - !memcmp(driver_algs[i].name, "authenc", 7) && |
936 | - !done) { |
937 | - char *name; |
938 | - |
939 | - name = driver_algs[i].name; |
940 | - memmove(name + 10, name + 7, strlen(name) - 7); |
941 | - memcpy(name + 7, "esn", 3); |
942 | - |
943 | - name = driver_algs[i].driver_name; |
944 | - memmove(name + 10, name + 7, strlen(name) - 7); |
945 | - memcpy(name + 7, "esn", 3); |
946 | - |
947 | - done = true; |
948 | - goto authencesn; |
949 | - } |
950 | - } |
951 | } |
952 | if (!list_empty(&priv->alg_list)) |
953 | dev_info(ctrldev, "%s algorithms registered in /proc/crypto\n", |
954 | diff --git a/drivers/crypto/caam/compat.h b/drivers/crypto/caam/compat.h |
955 | index cf15e78..762aeff 100644 |
956 | --- a/drivers/crypto/caam/compat.h |
957 | +++ b/drivers/crypto/caam/compat.h |
958 | @@ -23,7 +23,6 @@ |
959 | #include <linux/types.h> |
960 | #include <linux/debugfs.h> |
961 | #include <linux/circ_buf.h> |
962 | -#include <linux/string.h> |
963 | #include <net/xfrm.h> |
964 | |
965 | #include <crypto/algapi.h> |
966 | diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c |
967 | index 09b184a..5b2b5e6 100644 |
968 | --- a/drivers/crypto/talitos.c |
969 | +++ b/drivers/crypto/talitos.c |
970 | @@ -38,7 +38,6 @@ |
971 | #include <linux/spinlock.h> |
972 | #include <linux/rtnetlink.h> |
973 | #include <linux/slab.h> |
974 | -#include <linux/string.h> |
975 | |
976 | #include <crypto/algapi.h> |
977 | #include <crypto/aes.h> |
978 | @@ -1974,11 +1973,7 @@ struct talitos_alg_template { |
979 | }; |
980 | |
981 | static struct talitos_alg_template driver_algs[] = { |
982 | - /* |
983 | - * AEAD algorithms. These use a single-pass ipsec_esp descriptor. |
984 | - * authencesn(*,*) is also registered, although not present |
985 | - * explicitly here. |
986 | - */ |
987 | + /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */ |
988 | { .type = CRYPTO_ALG_TYPE_AEAD, |
989 | .alg.crypto = { |
990 | .cra_name = "authenc(hmac(sha1),cbc(aes))", |
991 | @@ -2820,9 +2815,7 @@ static int talitos_probe(struct platform_device *ofdev) |
992 | if (hw_supports(dev, driver_algs[i].desc_hdr_template)) { |
993 | struct talitos_crypto_alg *t_alg; |
994 | char *name = NULL; |
995 | - bool authenc = false; |
996 | |
997 | -authencesn: |
998 | t_alg = talitos_alg_alloc(dev, &driver_algs[i]); |
999 | if (IS_ERR(t_alg)) { |
1000 | err = PTR_ERR(t_alg); |
1001 | @@ -2837,8 +2830,6 @@ authencesn: |
1002 | err = crypto_register_alg( |
1003 | &t_alg->algt.alg.crypto); |
1004 | name = t_alg->algt.alg.crypto.cra_driver_name; |
1005 | - authenc = authenc ? !authenc : |
1006 | - !(bool)memcmp(name, "authenc", 7); |
1007 | break; |
1008 | case CRYPTO_ALG_TYPE_AHASH: |
1009 | err = crypto_register_ahash( |
1010 | @@ -2851,25 +2842,8 @@ authencesn: |
1011 | dev_err(dev, "%s alg registration failed\n", |
1012 | name); |
1013 | kfree(t_alg); |
1014 | - } else { |
1015 | + } else |
1016 | list_add_tail(&t_alg->entry, &priv->alg_list); |
1017 | - if (authenc) { |
1018 | - struct crypto_alg *alg = |
1019 | - &driver_algs[i].alg.crypto; |
1020 | - |
1021 | - name = alg->cra_name; |
1022 | - memmove(name + 10, name + 7, |
1023 | - strlen(name) - 7); |
1024 | - memcpy(name + 7, "esn", 3); |
1025 | - |
1026 | - name = alg->cra_driver_name; |
1027 | - memmove(name + 10, name + 7, |
1028 | - strlen(name) - 7); |
1029 | - memcpy(name + 7, "esn", 3); |
1030 | - |
1031 | - goto authencesn; |
1032 | - } |
1033 | - } |
1034 | } |
1035 | } |
1036 | if (!list_empty(&priv->alg_list)) |
1037 | diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c |
1038 | index e1d6253..b07cb37 100644 |
1039 | --- a/drivers/firmware/efivars.c |
1040 | +++ b/drivers/firmware/efivars.c |
1041 | @@ -1669,6 +1669,53 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, |
1042 | return count; |
1043 | } |
1044 | |
1045 | +static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor) |
1046 | +{ |
1047 | + struct efivar_entry *entry, *n; |
1048 | + struct efivars *efivars = &__efivars; |
1049 | + unsigned long strsize1, strsize2; |
1050 | + bool found = false; |
1051 | + |
1052 | + strsize1 = utf16_strsize(variable_name, 1024); |
1053 | + list_for_each_entry_safe(entry, n, &efivars->list, list) { |
1054 | + strsize2 = utf16_strsize(entry->var.VariableName, 1024); |
1055 | + if (strsize1 == strsize2 && |
1056 | + !memcmp(variable_name, &(entry->var.VariableName), |
1057 | + strsize2) && |
1058 | + !efi_guidcmp(entry->var.VendorGuid, |
1059 | + *vendor)) { |
1060 | + found = true; |
1061 | + break; |
1062 | + } |
1063 | + } |
1064 | + return found; |
1065 | +} |
1066 | + |
1067 | +/* |
1068 | + * Returns the size of variable_name, in bytes, including the |
1069 | + * terminating NULL character, or variable_name_size if no NULL |
1070 | + * character is found among the first variable_name_size bytes. |
1071 | + */ |
1072 | +static unsigned long var_name_strnsize(efi_char16_t *variable_name, |
1073 | + unsigned long variable_name_size) |
1074 | +{ |
1075 | + unsigned long len; |
1076 | + efi_char16_t c; |
1077 | + |
1078 | + /* |
1079 | + * The variable name is, by definition, a NULL-terminated |
1080 | + * string, so make absolutely sure that variable_name_size is |
1081 | + * the value we expect it to be. If not, return the real size. |
1082 | + */ |
1083 | + for (len = 2; len <= variable_name_size; len += sizeof(c)) { |
1084 | + c = variable_name[(len / sizeof(c)) - 1]; |
1085 | + if (!c) |
1086 | + break; |
1087 | + } |
1088 | + |
1089 | + return min(len, variable_name_size); |
1090 | +} |
1091 | + |
1092 | /* |
1093 | * Let's not leave out systab information that snuck into |
1094 | * the efivars driver |
1095 | @@ -1864,6 +1911,28 @@ void unregister_efivars(struct efivars *efivars) |
1096 | } |
1097 | EXPORT_SYMBOL_GPL(unregister_efivars); |
1098 | |
1099 | +/* |
1100 | + * Print a warning when duplicate EFI variables are encountered and |
1101 | + * disable the sysfs workqueue since the firmware is buggy. |
1102 | + */ |
1103 | +static void dup_variable_bug(efi_char16_t *s16, efi_guid_t *vendor_guid, |
1104 | + unsigned long len16) |
1105 | +{ |
1106 | + size_t i, len8 = len16 / sizeof(efi_char16_t); |
1107 | + char *s8; |
1108 | + |
1109 | + s8 = kzalloc(len8, GFP_KERNEL); |
1110 | + if (!s8) |
1111 | + return; |
1112 | + |
1113 | + for (i = 0; i < len8; i++) |
1114 | + s8[i] = s16[i]; |
1115 | + |
1116 | + printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n", |
1117 | + s8, vendor_guid); |
1118 | + kfree(s8); |
1119 | +} |
1120 | + |
1121 | int register_efivars(struct efivars *efivars, |
1122 | const struct efivar_operations *ops, |
1123 | struct kobject *parent_kobj) |
1124 | @@ -1912,6 +1981,24 @@ int register_efivars(struct efivars *efivars, |
1125 | &vendor_guid); |
1126 | switch (status) { |
1127 | case EFI_SUCCESS: |
1128 | + variable_name_size = var_name_strnsize(variable_name, |
1129 | + variable_name_size); |
1130 | + |
1131 | + /* |
1132 | + * Some firmware implementations return the |
1133 | + * same variable name on multiple calls to |
1134 | + * get_next_variable(). Terminate the loop |
1135 | + * immediately as there is no guarantee that |
1136 | + * we'll ever see a different variable name, |
1137 | + * and may end up looping here forever. |
1138 | + */ |
1139 | + if (variable_is_present(variable_name, &vendor_guid)) { |
1140 | + dup_variable_bug(variable_name, &vendor_guid, |
1141 | + variable_name_size); |
1142 | + status = EFI_NOT_FOUND; |
1143 | + break; |
1144 | + } |
1145 | + |
1146 | efivar_create_sysfs_entry(efivars, |
1147 | variable_name_size, |
1148 | variable_name, |
1149 | diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c |
1150 | index 80aa1fc..e6e4df7 100644 |
1151 | --- a/drivers/gpu/drm/i915/intel_display.c |
1152 | +++ b/drivers/gpu/drm/i915/intel_display.c |
1153 | @@ -7420,8 +7420,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, |
1154 | { |
1155 | struct drm_device *dev = crtc->dev; |
1156 | struct drm_i915_private *dev_priv = dev->dev_private; |
1157 | - struct intel_framebuffer *intel_fb; |
1158 | - struct drm_i915_gem_object *obj; |
1159 | + struct drm_framebuffer *old_fb = crtc->fb; |
1160 | + struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj; |
1161 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1162 | struct intel_unpin_work *work; |
1163 | unsigned long flags; |
1164 | @@ -7446,8 +7446,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, |
1165 | |
1166 | work->event = event; |
1167 | work->crtc = crtc; |
1168 | - intel_fb = to_intel_framebuffer(crtc->fb); |
1169 | - work->old_fb_obj = intel_fb->obj; |
1170 | + work->old_fb_obj = to_intel_framebuffer(old_fb)->obj; |
1171 | INIT_WORK(&work->work, intel_unpin_work_fn); |
1172 | |
1173 | ret = drm_vblank_get(dev, intel_crtc->pipe); |
1174 | @@ -7467,9 +7466,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, |
1175 | intel_crtc->unpin_work = work; |
1176 | spin_unlock_irqrestore(&dev->event_lock, flags); |
1177 | |
1178 | - intel_fb = to_intel_framebuffer(fb); |
1179 | - obj = intel_fb->obj; |
1180 | - |
1181 | if (atomic_read(&intel_crtc->unpin_work_count) >= 2) |
1182 | flush_workqueue(dev_priv->wq); |
1183 | |
1184 | @@ -7507,6 +7503,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, |
1185 | |
1186 | cleanup_pending: |
1187 | atomic_dec(&intel_crtc->unpin_work_count); |
1188 | + crtc->fb = old_fb; |
1189 | atomic_sub(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip); |
1190 | drm_gem_object_unreference(&work->old_fb_obj->base); |
1191 | drm_gem_object_unreference(&obj->base); |
1192 | diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c |
1193 | index 2e1c10a..73ce6e9 100644 |
1194 | --- a/drivers/gpu/drm/i915/intel_dp.c |
1195 | +++ b/drivers/gpu/drm/i915/intel_dp.c |
1196 | @@ -788,6 +788,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, |
1197 | struct intel_dp_m_n m_n; |
1198 | int pipe = intel_crtc->pipe; |
1199 | enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder; |
1200 | + int target_clock; |
1201 | |
1202 | /* |
1203 | * Find the lane count in the intel_encoder private |
1204 | @@ -803,13 +804,22 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, |
1205 | } |
1206 | } |
1207 | |
1208 | + target_clock = mode->clock; |
1209 | + for_each_encoder_on_crtc(dev, crtc, intel_encoder) { |
1210 | + if (intel_encoder->type == INTEL_OUTPUT_EDP) { |
1211 | + target_clock = intel_edp_target_clock(intel_encoder, |
1212 | + mode); |
1213 | + break; |
1214 | + } |
1215 | + } |
1216 | + |
1217 | /* |
1218 | * Compute the GMCH and Link ratios. The '3' here is |
1219 | * the number of bytes_per_pixel post-LUT, which we always |
1220 | * set up for 8-bits of R/G/B, or 3 bytes total. |
1221 | */ |
1222 | intel_dp_compute_m_n(intel_crtc->bpp, lane_count, |
1223 | - mode->clock, adjusted_mode->clock, &m_n); |
1224 | + target_clock, adjusted_mode->clock, &m_n); |
1225 | |
1226 | if (IS_HASWELL(dev)) { |
1227 | I915_WRITE(PIPE_DATA_M1(cpu_transcoder), |
1228 | diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h |
1229 | index 266e2ae..160a309 100644 |
1230 | --- a/drivers/hid/hid-ids.h |
1231 | +++ b/drivers/hid/hid-ids.h |
1232 | @@ -587,6 +587,9 @@ |
1233 | #define USB_VENDOR_ID_MONTEREY 0x0566 |
1234 | #define USB_DEVICE_ID_GENIUS_KB29E 0x3004 |
1235 | |
1236 | +#define USB_VENDOR_ID_MSI 0x1770 |
1237 | +#define USB_DEVICE_ID_MSI_GX680R_LED_PANEL 0xff00 |
1238 | + |
1239 | #define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400 |
1240 | #define USB_DEVICE_ID_N_S_HARMONY 0xc359 |
1241 | |
1242 | @@ -678,6 +681,9 @@ |
1243 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001 0x3001 |
1244 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008 |
1245 | |
1246 | +#define USB_VENDOR_ID_REALTEK 0x0bda |
1247 | +#define USB_DEVICE_ID_REALTEK_READER 0x0152 |
1248 | + |
1249 | #define USB_VENDOR_ID_ROCCAT 0x1e7d |
1250 | #define USB_DEVICE_ID_ROCCAT_ARVO 0x30d4 |
1251 | #define USB_DEVICE_ID_ROCCAT_ISKU 0x319c |
1252 | diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c |
1253 | index e0e6abf..19b8360 100644 |
1254 | --- a/drivers/hid/usbhid/hid-quirks.c |
1255 | +++ b/drivers/hid/usbhid/hid-quirks.c |
1256 | @@ -73,6 +73,7 @@ static const struct hid_blacklist { |
1257 | { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, |
1258 | { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, |
1259 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, |
1260 | + { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, |
1261 | { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, |
1262 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, |
1263 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, |
1264 | @@ -80,6 +81,7 @@ static const struct hid_blacklist { |
1265 | { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, |
1266 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001, HID_QUIRK_NOGET }, |
1267 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET }, |
1268 | + { USB_VENDOR_ID_REALTEK, USB_DEVICE_ID_REALTEK_READER, HID_QUIRK_NO_INIT_REPORTS }, |
1269 | { USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET }, |
1270 | { USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780, HID_QUIRK_NOGET }, |
1271 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, |
1272 | diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c |
1273 | index c1c74e0..4647b50 100644 |
1274 | --- a/drivers/iommu/amd_iommu.c |
1275 | +++ b/drivers/iommu/amd_iommu.c |
1276 | @@ -2466,18 +2466,16 @@ static int device_change_notifier(struct notifier_block *nb, |
1277 | |
1278 | /* allocate a protection domain if a device is added */ |
1279 | dma_domain = find_protection_domain(devid); |
1280 | - if (dma_domain) |
1281 | - goto out; |
1282 | - dma_domain = dma_ops_domain_alloc(); |
1283 | - if (!dma_domain) |
1284 | - goto out; |
1285 | - dma_domain->target_dev = devid; |
1286 | - |
1287 | - spin_lock_irqsave(&iommu_pd_list_lock, flags); |
1288 | - list_add_tail(&dma_domain->list, &iommu_pd_list); |
1289 | - spin_unlock_irqrestore(&iommu_pd_list_lock, flags); |
1290 | - |
1291 | - dev_data = get_dev_data(dev); |
1292 | + if (!dma_domain) { |
1293 | + dma_domain = dma_ops_domain_alloc(); |
1294 | + if (!dma_domain) |
1295 | + goto out; |
1296 | + dma_domain->target_dev = devid; |
1297 | + |
1298 | + spin_lock_irqsave(&iommu_pd_list_lock, flags); |
1299 | + list_add_tail(&dma_domain->list, &iommu_pd_list); |
1300 | + spin_unlock_irqrestore(&iommu_pd_list_lock, flags); |
1301 | + } |
1302 | |
1303 | dev->archdata.dma_ops = &amd_iommu_dma_ops; |
1304 | |
1305 | diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c |
1306 | index 45e5d06..dd53210 100644 |
1307 | --- a/drivers/media/pci/bt8xx/bttv-driver.c |
1308 | +++ b/drivers/media/pci/bt8xx/bttv-driver.c |
1309 | @@ -250,17 +250,19 @@ static u8 SRAM_Table[][60] = |
1310 | vdelay start of active video in 2 * field lines relative to |
1311 | trailing edge of /VRESET pulse (VDELAY register). |
1312 | sheight height of active video in 2 * field lines. |
1313 | + extraheight Added to sheight for cropcap.bounds.height only |
1314 | videostart0 ITU-R frame line number of the line corresponding |
1315 | to vdelay in the first field. */ |
1316 | #define CROPCAP(minhdelayx1, hdelayx1, swidth, totalwidth, sqwidth, \ |
1317 | - vdelay, sheight, videostart0) \ |
1318 | + vdelay, sheight, extraheight, videostart0) \ |
1319 | .cropcap.bounds.left = minhdelayx1, \ |
1320 | /* * 2 because vertically we count field lines times two, */ \ |
1321 | /* e.g. 23 * 2 to 23 * 2 + 576 in PAL-BGHI defrect. */ \ |
1322 | .cropcap.bounds.top = (videostart0) * 2 - (vdelay) + MIN_VDELAY, \ |
1323 | /* 4 is a safety margin at the end of the line. */ \ |
1324 | .cropcap.bounds.width = (totalwidth) - (minhdelayx1) - 4, \ |
1325 | - .cropcap.bounds.height = (sheight) + (vdelay) - MIN_VDELAY, \ |
1326 | + .cropcap.bounds.height = (sheight) + (extraheight) + (vdelay) - \ |
1327 | + MIN_VDELAY, \ |
1328 | .cropcap.defrect.left = hdelayx1, \ |
1329 | .cropcap.defrect.top = (videostart0) * 2, \ |
1330 | .cropcap.defrect.width = swidth, \ |
1331 | @@ -301,9 +303,10 @@ const struct bttv_tvnorm bttv_tvnorms[] = { |
1332 | /* totalwidth */ 1135, |
1333 | /* sqwidth */ 944, |
1334 | /* vdelay */ 0x20, |
1335 | - /* bt878 (and bt848?) can capture another |
1336 | - line below active video. */ |
1337 | - /* sheight */ (576 + 2) + 0x20 - 2, |
1338 | + /* sheight */ 576, |
1339 | + /* bt878 (and bt848?) can capture another |
1340 | + line below active video. */ |
1341 | + /* extraheight */ 2, |
1342 | /* videostart0 */ 23) |
1343 | },{ |
1344 | .v4l2_id = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR, |
1345 | @@ -330,6 +333,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = { |
1346 | /* sqwidth */ 780, |
1347 | /* vdelay */ 0x1a, |
1348 | /* sheight */ 480, |
1349 | + /* extraheight */ 0, |
1350 | /* videostart0 */ 23) |
1351 | },{ |
1352 | .v4l2_id = V4L2_STD_SECAM, |
1353 | @@ -355,6 +359,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = { |
1354 | /* sqwidth */ 944, |
1355 | /* vdelay */ 0x20, |
1356 | /* sheight */ 576, |
1357 | + /* extraheight */ 0, |
1358 | /* videostart0 */ 23) |
1359 | },{ |
1360 | .v4l2_id = V4L2_STD_PAL_Nc, |
1361 | @@ -380,6 +385,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = { |
1362 | /* sqwidth */ 780, |
1363 | /* vdelay */ 0x1a, |
1364 | /* sheight */ 576, |
1365 | + /* extraheight */ 0, |
1366 | /* videostart0 */ 23) |
1367 | },{ |
1368 | .v4l2_id = V4L2_STD_PAL_M, |
1369 | @@ -405,6 +411,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = { |
1370 | /* sqwidth */ 780, |
1371 | /* vdelay */ 0x1a, |
1372 | /* sheight */ 480, |
1373 | + /* extraheight */ 0, |
1374 | /* videostart0 */ 23) |
1375 | },{ |
1376 | .v4l2_id = V4L2_STD_PAL_N, |
1377 | @@ -430,6 +437,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = { |
1378 | /* sqwidth */ 944, |
1379 | /* vdelay */ 0x20, |
1380 | /* sheight */ 576, |
1381 | + /* extraheight */ 0, |
1382 | /* videostart0 */ 23) |
1383 | },{ |
1384 | .v4l2_id = V4L2_STD_NTSC_M_JP, |
1385 | @@ -455,6 +463,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = { |
1386 | /* sqwidth */ 780, |
1387 | /* vdelay */ 0x16, |
1388 | /* sheight */ 480, |
1389 | + /* extraheight */ 0, |
1390 | /* videostart0 */ 23) |
1391 | },{ |
1392 | /* that one hopefully works with the strange timing |
1393 | @@ -484,6 +493,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = { |
1394 | /* sqwidth */ 944, |
1395 | /* vdelay */ 0x1a, |
1396 | /* sheight */ 480, |
1397 | + /* extraheight */ 0, |
1398 | /* videostart0 */ 23) |
1399 | } |
1400 | }; |
1401 | diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c |
1402 | index 272f81a..27cdf1f 100644 |
1403 | --- a/drivers/net/bonding/bond_main.c |
1404 | +++ b/drivers/net/bonding/bond_main.c |
1405 | @@ -1955,12 +1955,11 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) |
1406 | return -EINVAL; |
1407 | } |
1408 | |
1409 | + write_unlock_bh(&bond->lock); |
1410 | /* unregister rx_handler early so bond_handle_frame wouldn't be called |
1411 | * for this slave anymore. |
1412 | */ |
1413 | netdev_rx_handler_unregister(slave_dev); |
1414 | - write_unlock_bh(&bond->lock); |
1415 | - synchronize_net(); |
1416 | write_lock_bh(&bond->lock); |
1417 | |
1418 | if (!bond->params.fail_over_mac) { |
1419 | diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c |
1420 | index 1c9e09f..ea7a388 100644 |
1421 | --- a/drivers/net/bonding/bond_sysfs.c |
1422 | +++ b/drivers/net/bonding/bond_sysfs.c |
1423 | @@ -183,6 +183,11 @@ int bond_create_slave_symlinks(struct net_device *master, |
1424 | sprintf(linkname, "slave_%s", slave->name); |
1425 | ret = sysfs_create_link(&(master->dev.kobj), &(slave->dev.kobj), |
1426 | linkname); |
1427 | + |
1428 | + /* free the master link created earlier in case of error */ |
1429 | + if (ret) |
1430 | + sysfs_remove_link(&(slave->dev.kobj), "master"); |
1431 | + |
1432 | return ret; |
1433 | |
1434 | } |
1435 | @@ -522,7 +527,7 @@ static ssize_t bonding_store_arp_interval(struct device *d, |
1436 | goto out; |
1437 | } |
1438 | if (new_value < 0) { |
1439 | - pr_err("%s: Invalid arp_interval value %d not in range 1-%d; rejected.\n", |
1440 | + pr_err("%s: Invalid arp_interval value %d not in range 0-%d; rejected.\n", |
1441 | bond->dev->name, new_value, INT_MAX); |
1442 | ret = -EINVAL; |
1443 | goto out; |
1444 | @@ -537,14 +542,15 @@ static ssize_t bonding_store_arp_interval(struct device *d, |
1445 | pr_info("%s: Setting ARP monitoring interval to %d.\n", |
1446 | bond->dev->name, new_value); |
1447 | bond->params.arp_interval = new_value; |
1448 | - if (bond->params.miimon) { |
1449 | - pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", |
1450 | - bond->dev->name, bond->dev->name); |
1451 | - bond->params.miimon = 0; |
1452 | - } |
1453 | - if (!bond->params.arp_targets[0]) { |
1454 | - pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", |
1455 | - bond->dev->name); |
1456 | + if (new_value) { |
1457 | + if (bond->params.miimon) { |
1458 | + pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", |
1459 | + bond->dev->name, bond->dev->name); |
1460 | + bond->params.miimon = 0; |
1461 | + } |
1462 | + if (!bond->params.arp_targets[0]) |
1463 | + pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", |
1464 | + bond->dev->name); |
1465 | } |
1466 | if (bond->dev->flags & IFF_UP) { |
1467 | /* If the interface is up, we may need to fire off |
1468 | @@ -552,10 +558,13 @@ static ssize_t bonding_store_arp_interval(struct device *d, |
1469 | * timer will get fired off when the open function |
1470 | * is called. |
1471 | */ |
1472 | - cancel_delayed_work_sync(&bond->mii_work); |
1473 | - queue_delayed_work(bond->wq, &bond->arp_work, 0); |
1474 | + if (!new_value) { |
1475 | + cancel_delayed_work_sync(&bond->arp_work); |
1476 | + } else { |
1477 | + cancel_delayed_work_sync(&bond->mii_work); |
1478 | + queue_delayed_work(bond->wq, &bond->arp_work, 0); |
1479 | + } |
1480 | } |
1481 | - |
1482 | out: |
1483 | rtnl_unlock(); |
1484 | return ret; |
1485 | @@ -697,7 +706,7 @@ static ssize_t bonding_store_downdelay(struct device *d, |
1486 | } |
1487 | if (new_value < 0) { |
1488 | pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", |
1489 | - bond->dev->name, new_value, 1, INT_MAX); |
1490 | + bond->dev->name, new_value, 0, INT_MAX); |
1491 | ret = -EINVAL; |
1492 | goto out; |
1493 | } else { |
1494 | @@ -752,8 +761,8 @@ static ssize_t bonding_store_updelay(struct device *d, |
1495 | goto out; |
1496 | } |
1497 | if (new_value < 0) { |
1498 | - pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", |
1499 | - bond->dev->name, new_value, 1, INT_MAX); |
1500 | + pr_err("%s: Invalid up delay value %d not in range %d-%d; rejected.\n", |
1501 | + bond->dev->name, new_value, 0, INT_MAX); |
1502 | ret = -EINVAL; |
1503 | goto out; |
1504 | } else { |
1505 | @@ -963,37 +972,37 @@ static ssize_t bonding_store_miimon(struct device *d, |
1506 | } |
1507 | if (new_value < 0) { |
1508 | pr_err("%s: Invalid miimon value %d not in range %d-%d; rejected.\n", |
1509 | - bond->dev->name, new_value, 1, INT_MAX); |
1510 | + bond->dev->name, new_value, 0, INT_MAX); |
1511 | ret = -EINVAL; |
1512 | goto out; |
1513 | - } else { |
1514 | - pr_info("%s: Setting MII monitoring interval to %d.\n", |
1515 | - bond->dev->name, new_value); |
1516 | - bond->params.miimon = new_value; |
1517 | - if (bond->params.updelay) |
1518 | - pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n", |
1519 | - bond->dev->name, |
1520 | - bond->params.updelay * bond->params.miimon); |
1521 | - if (bond->params.downdelay) |
1522 | - pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n", |
1523 | - bond->dev->name, |
1524 | - bond->params.downdelay * bond->params.miimon); |
1525 | - if (bond->params.arp_interval) { |
1526 | - pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n", |
1527 | - bond->dev->name); |
1528 | - bond->params.arp_interval = 0; |
1529 | - if (bond->params.arp_validate) { |
1530 | - bond->params.arp_validate = |
1531 | - BOND_ARP_VALIDATE_NONE; |
1532 | - } |
1533 | - } |
1534 | - |
1535 | - if (bond->dev->flags & IFF_UP) { |
1536 | - /* If the interface is up, we may need to fire off |
1537 | - * the MII timer. If the interface is down, the |
1538 | - * timer will get fired off when the open function |
1539 | - * is called. |
1540 | - */ |
1541 | + } |
1542 | + pr_info("%s: Setting MII monitoring interval to %d.\n", |
1543 | + bond->dev->name, new_value); |
1544 | + bond->params.miimon = new_value; |
1545 | + if (bond->params.updelay) |
1546 | + pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n", |
1547 | + bond->dev->name, |
1548 | + bond->params.updelay * bond->params.miimon); |
1549 | + if (bond->params.downdelay) |
1550 | + pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n", |
1551 | + bond->dev->name, |
1552 | + bond->params.downdelay * bond->params.miimon); |
1553 | + if (new_value && bond->params.arp_interval) { |
1554 | + pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n", |
1555 | + bond->dev->name); |
1556 | + bond->params.arp_interval = 0; |
1557 | + if (bond->params.arp_validate) |
1558 | + bond->params.arp_validate = BOND_ARP_VALIDATE_NONE; |
1559 | + } |
1560 | + if (bond->dev->flags & IFF_UP) { |
1561 | + /* If the interface is up, we may need to fire off |
1562 | + * the MII timer. If the interface is down, the |
1563 | + * timer will get fired off when the open function |
1564 | + * is called. |
1565 | + */ |
1566 | + if (!new_value) { |
1567 | + cancel_delayed_work_sync(&bond->mii_work); |
1568 | + } else { |
1569 | cancel_delayed_work_sync(&bond->arp_work); |
1570 | queue_delayed_work(bond->wq, &bond->mii_work, 0); |
1571 | } |
1572 | diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c |
1573 | index 11d1062..08a606c 100644 |
1574 | --- a/drivers/net/can/sja1000/plx_pci.c |
1575 | +++ b/drivers/net/can/sja1000/plx_pci.c |
1576 | @@ -348,7 +348,7 @@ static inline int plx_pci_check_sja1000(const struct sja1000_priv *priv) |
1577 | */ |
1578 | if ((priv->read_reg(priv, REG_CR) & REG_CR_BASICCAN_INITIAL_MASK) == |
1579 | REG_CR_BASICCAN_INITIAL && |
1580 | - (priv->read_reg(priv, REG_SR) == REG_SR_BASICCAN_INITIAL) && |
1581 | + (priv->read_reg(priv, SJA1000_REG_SR) == REG_SR_BASICCAN_INITIAL) && |
1582 | (priv->read_reg(priv, REG_IR) == REG_IR_BASICCAN_INITIAL)) |
1583 | flag = 1; |
1584 | |
1585 | @@ -360,7 +360,7 @@ static inline int plx_pci_check_sja1000(const struct sja1000_priv *priv) |
1586 | * See states on p. 23 of the Datasheet. |
1587 | */ |
1588 | if (priv->read_reg(priv, REG_MOD) == REG_MOD_PELICAN_INITIAL && |
1589 | - priv->read_reg(priv, REG_SR) == REG_SR_PELICAN_INITIAL && |
1590 | + priv->read_reg(priv, SJA1000_REG_SR) == REG_SR_PELICAN_INITIAL && |
1591 | priv->read_reg(priv, REG_IR) == REG_IR_PELICAN_INITIAL) |
1592 | return flag; |
1593 | |
1594 | diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c |
1595 | index 83ee11e..43921f9 100644 |
1596 | --- a/drivers/net/can/sja1000/sja1000.c |
1597 | +++ b/drivers/net/can/sja1000/sja1000.c |
1598 | @@ -91,7 +91,7 @@ static void sja1000_write_cmdreg(struct sja1000_priv *priv, u8 val) |
1599 | */ |
1600 | spin_lock_irqsave(&priv->cmdreg_lock, flags); |
1601 | priv->write_reg(priv, REG_CMR, val); |
1602 | - priv->read_reg(priv, REG_SR); |
1603 | + priv->read_reg(priv, SJA1000_REG_SR); |
1604 | spin_unlock_irqrestore(&priv->cmdreg_lock, flags); |
1605 | } |
1606 | |
1607 | @@ -499,7 +499,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) |
1608 | |
1609 | while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) { |
1610 | n++; |
1611 | - status = priv->read_reg(priv, REG_SR); |
1612 | + status = priv->read_reg(priv, SJA1000_REG_SR); |
1613 | /* check for absent controller due to hw unplug */ |
1614 | if (status == 0xFF && sja1000_is_absent(priv)) |
1615 | return IRQ_NONE; |
1616 | @@ -526,7 +526,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) |
1617 | /* receive interrupt */ |
1618 | while (status & SR_RBS) { |
1619 | sja1000_rx(dev); |
1620 | - status = priv->read_reg(priv, REG_SR); |
1621 | + status = priv->read_reg(priv, SJA1000_REG_SR); |
1622 | /* check for absent controller */ |
1623 | if (status == 0xFF && sja1000_is_absent(priv)) |
1624 | return IRQ_NONE; |
1625 | diff --git a/drivers/net/can/sja1000/sja1000.h b/drivers/net/can/sja1000/sja1000.h |
1626 | index afa9984..aa48e05 100644 |
1627 | --- a/drivers/net/can/sja1000/sja1000.h |
1628 | +++ b/drivers/net/can/sja1000/sja1000.h |
1629 | @@ -56,7 +56,7 @@ |
1630 | /* SJA1000 registers - manual section 6.4 (Pelican Mode) */ |
1631 | #define REG_MOD 0x00 |
1632 | #define REG_CMR 0x01 |
1633 | -#define REG_SR 0x02 |
1634 | +#define SJA1000_REG_SR 0x02 |
1635 | #define REG_IR 0x03 |
1636 | #define REG_IER 0x04 |
1637 | #define REG_ALC 0x0B |
1638 | diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e.h b/drivers/net/ethernet/atheros/atl1e/atl1e.h |
1639 | index 829b5ad..edfdf6b 100644 |
1640 | --- a/drivers/net/ethernet/atheros/atl1e/atl1e.h |
1641 | +++ b/drivers/net/ethernet/atheros/atl1e/atl1e.h |
1642 | @@ -438,7 +438,6 @@ struct atl1e_adapter { |
1643 | struct atl1e_hw hw; |
1644 | struct atl1e_hw_stats hw_stats; |
1645 | |
1646 | - bool have_msi; |
1647 | u32 wol; |
1648 | u16 link_speed; |
1649 | u16 link_duplex; |
1650 | diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c |
1651 | index e4466a3..35faab7 100644 |
1652 | --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c |
1653 | +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c |
1654 | @@ -1851,34 +1851,19 @@ static void atl1e_free_irq(struct atl1e_adapter *adapter) |
1655 | struct net_device *netdev = adapter->netdev; |
1656 | |
1657 | free_irq(adapter->pdev->irq, netdev); |
1658 | - |
1659 | - if (adapter->have_msi) |
1660 | - pci_disable_msi(adapter->pdev); |
1661 | } |
1662 | |
1663 | static int atl1e_request_irq(struct atl1e_adapter *adapter) |
1664 | { |
1665 | struct pci_dev *pdev = adapter->pdev; |
1666 | struct net_device *netdev = adapter->netdev; |
1667 | - int flags = 0; |
1668 | int err = 0; |
1669 | |
1670 | - adapter->have_msi = true; |
1671 | - err = pci_enable_msi(pdev); |
1672 | - if (err) { |
1673 | - netdev_dbg(netdev, |
1674 | - "Unable to allocate MSI interrupt Error: %d\n", err); |
1675 | - adapter->have_msi = false; |
1676 | - } |
1677 | - |
1678 | - if (!adapter->have_msi) |
1679 | - flags |= IRQF_SHARED; |
1680 | - err = request_irq(pdev->irq, atl1e_intr, flags, netdev->name, netdev); |
1681 | + err = request_irq(pdev->irq, atl1e_intr, IRQF_SHARED, netdev->name, |
1682 | + netdev); |
1683 | if (err) { |
1684 | netdev_dbg(adapter->netdev, |
1685 | "Unable to allocate interrupt Error: %d\n", err); |
1686 | - if (adapter->have_msi) |
1687 | - pci_disable_msi(pdev); |
1688 | return err; |
1689 | } |
1690 | netdev_dbg(netdev, "atl1e_request_irq OK\n"); |
1691 | diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c |
1692 | index 3ec98f2..8a5253c 100644 |
1693 | --- a/drivers/net/ethernet/broadcom/tg3.c |
1694 | +++ b/drivers/net/ethernet/broadcom/tg3.c |
1695 | @@ -14403,8 +14403,11 @@ static void tg3_read_vpd(struct tg3 *tp) |
1696 | if (j + len > block_end) |
1697 | goto partno; |
1698 | |
1699 | - memcpy(tp->fw_ver, &vpd_data[j], len); |
1700 | - strncat(tp->fw_ver, " bc ", vpdlen - len - 1); |
1701 | + if (len >= sizeof(tp->fw_ver)) |
1702 | + len = sizeof(tp->fw_ver) - 1; |
1703 | + memset(tp->fw_ver, 0, sizeof(tp->fw_ver)); |
1704 | + snprintf(tp->fw_ver, sizeof(tp->fw_ver), "%.*s bc ", len, |
1705 | + &vpd_data[j]); |
1706 | } |
1707 | |
1708 | partno: |
1709 | diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c |
1710 | index c73472c..d67de83 100644 |
1711 | --- a/drivers/net/ethernet/davicom/dm9000.c |
1712 | +++ b/drivers/net/ethernet/davicom/dm9000.c |
1713 | @@ -257,6 +257,107 @@ static void dm9000_dumpblk_32bit(void __iomem *reg, int count) |
1714 | tmp = readl(reg); |
1715 | } |
1716 | |
1717 | +/* |
1718 | + * Sleep, either by using msleep() or if we are suspending, then |
1719 | + * use mdelay() to sleep. |
1720 | + */ |
1721 | +static void dm9000_msleep(board_info_t *db, unsigned int ms) |
1722 | +{ |
1723 | + if (db->in_suspend) |
1724 | + mdelay(ms); |
1725 | + else |
1726 | + msleep(ms); |
1727 | +} |
1728 | + |
1729 | +/* Read a word from phyxcer */ |
1730 | +static int |
1731 | +dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) |
1732 | +{ |
1733 | + board_info_t *db = netdev_priv(dev); |
1734 | + unsigned long flags; |
1735 | + unsigned int reg_save; |
1736 | + int ret; |
1737 | + |
1738 | + mutex_lock(&db->addr_lock); |
1739 | + |
1740 | + spin_lock_irqsave(&db->lock, flags); |
1741 | + |
1742 | + /* Save previous register address */ |
1743 | + reg_save = readb(db->io_addr); |
1744 | + |
1745 | + /* Fill the phyxcer register into REG_0C */ |
1746 | + iow(db, DM9000_EPAR, DM9000_PHY | reg); |
1747 | + |
1748 | + /* Issue phyxcer read command */ |
1749 | + iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS); |
1750 | + |
1751 | + writeb(reg_save, db->io_addr); |
1752 | + spin_unlock_irqrestore(&db->lock, flags); |
1753 | + |
1754 | + dm9000_msleep(db, 1); /* Wait read complete */ |
1755 | + |
1756 | + spin_lock_irqsave(&db->lock, flags); |
1757 | + reg_save = readb(db->io_addr); |
1758 | + |
1759 | + iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */ |
1760 | + |
1761 | + /* The read data keeps on REG_0D & REG_0E */ |
1762 | + ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL); |
1763 | + |
1764 | + /* restore the previous address */ |
1765 | + writeb(reg_save, db->io_addr); |
1766 | + spin_unlock_irqrestore(&db->lock, flags); |
1767 | + |
1768 | + mutex_unlock(&db->addr_lock); |
1769 | + |
1770 | + dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret); |
1771 | + return ret; |
1772 | +} |
1773 | + |
1774 | +/* Write a word to phyxcer */ |
1775 | +static void |
1776 | +dm9000_phy_write(struct net_device *dev, |
1777 | + int phyaddr_unused, int reg, int value) |
1778 | +{ |
1779 | + board_info_t *db = netdev_priv(dev); |
1780 | + unsigned long flags; |
1781 | + unsigned long reg_save; |
1782 | + |
1783 | + dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value); |
1784 | + mutex_lock(&db->addr_lock); |
1785 | + |
1786 | + spin_lock_irqsave(&db->lock, flags); |
1787 | + |
1788 | + /* Save previous register address */ |
1789 | + reg_save = readb(db->io_addr); |
1790 | + |
1791 | + /* Fill the phyxcer register into REG_0C */ |
1792 | + iow(db, DM9000_EPAR, DM9000_PHY | reg); |
1793 | + |
1794 | + /* Fill the written data into REG_0D & REG_0E */ |
1795 | + iow(db, DM9000_EPDRL, value); |
1796 | + iow(db, DM9000_EPDRH, value >> 8); |
1797 | + |
1798 | + /* Issue phyxcer write command */ |
1799 | + iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW); |
1800 | + |
1801 | + writeb(reg_save, db->io_addr); |
1802 | + spin_unlock_irqrestore(&db->lock, flags); |
1803 | + |
1804 | + dm9000_msleep(db, 1); /* Wait write complete */ |
1805 | + |
1806 | + spin_lock_irqsave(&db->lock, flags); |
1807 | + reg_save = readb(db->io_addr); |
1808 | + |
1809 | + iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */ |
1810 | + |
1811 | + /* restore the previous address */ |
1812 | + writeb(reg_save, db->io_addr); |
1813 | + |
1814 | + spin_unlock_irqrestore(&db->lock, flags); |
1815 | + mutex_unlock(&db->addr_lock); |
1816 | +} |
1817 | + |
1818 | /* dm9000_set_io |
1819 | * |
1820 | * select the specified set of io routines to use with the |
1821 | @@ -794,6 +895,9 @@ dm9000_init_dm9000(struct net_device *dev) |
1822 | |
1823 | iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */ |
1824 | |
1825 | + dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */ |
1826 | + dm9000_phy_write(dev, 0, MII_DM_DSPCR, DSPCR_INIT_PARAM); /* Init */ |
1827 | + |
1828 | ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0; |
1829 | |
1830 | /* if wol is needed, then always set NCR_WAKEEN otherwise we end |
1831 | @@ -1200,109 +1304,6 @@ dm9000_open(struct net_device *dev) |
1832 | return 0; |
1833 | } |
1834 | |
1835 | -/* |
1836 | - * Sleep, either by using msleep() or if we are suspending, then |
1837 | - * use mdelay() to sleep. |
1838 | - */ |
1839 | -static void dm9000_msleep(board_info_t *db, unsigned int ms) |
1840 | -{ |
1841 | - if (db->in_suspend) |
1842 | - mdelay(ms); |
1843 | - else |
1844 | - msleep(ms); |
1845 | -} |
1846 | - |
1847 | -/* |
1848 | - * Read a word from phyxcer |
1849 | - */ |
1850 | -static int |
1851 | -dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) |
1852 | -{ |
1853 | - board_info_t *db = netdev_priv(dev); |
1854 | - unsigned long flags; |
1855 | - unsigned int reg_save; |
1856 | - int ret; |
1857 | - |
1858 | - mutex_lock(&db->addr_lock); |
1859 | - |
1860 | - spin_lock_irqsave(&db->lock,flags); |
1861 | - |
1862 | - /* Save previous register address */ |
1863 | - reg_save = readb(db->io_addr); |
1864 | - |
1865 | - /* Fill the phyxcer register into REG_0C */ |
1866 | - iow(db, DM9000_EPAR, DM9000_PHY | reg); |
1867 | - |
1868 | - iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS); /* Issue phyxcer read command */ |
1869 | - |
1870 | - writeb(reg_save, db->io_addr); |
1871 | - spin_unlock_irqrestore(&db->lock,flags); |
1872 | - |
1873 | - dm9000_msleep(db, 1); /* Wait read complete */ |
1874 | - |
1875 | - spin_lock_irqsave(&db->lock,flags); |
1876 | - reg_save = readb(db->io_addr); |
1877 | - |
1878 | - iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */ |
1879 | - |
1880 | - /* The read data keeps on REG_0D & REG_0E */ |
1881 | - ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL); |
1882 | - |
1883 | - /* restore the previous address */ |
1884 | - writeb(reg_save, db->io_addr); |
1885 | - spin_unlock_irqrestore(&db->lock,flags); |
1886 | - |
1887 | - mutex_unlock(&db->addr_lock); |
1888 | - |
1889 | - dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret); |
1890 | - return ret; |
1891 | -} |
1892 | - |
1893 | -/* |
1894 | - * Write a word to phyxcer |
1895 | - */ |
1896 | -static void |
1897 | -dm9000_phy_write(struct net_device *dev, |
1898 | - int phyaddr_unused, int reg, int value) |
1899 | -{ |
1900 | - board_info_t *db = netdev_priv(dev); |
1901 | - unsigned long flags; |
1902 | - unsigned long reg_save; |
1903 | - |
1904 | - dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value); |
1905 | - mutex_lock(&db->addr_lock); |
1906 | - |
1907 | - spin_lock_irqsave(&db->lock,flags); |
1908 | - |
1909 | - /* Save previous register address */ |
1910 | - reg_save = readb(db->io_addr); |
1911 | - |
1912 | - /* Fill the phyxcer register into REG_0C */ |
1913 | - iow(db, DM9000_EPAR, DM9000_PHY | reg); |
1914 | - |
1915 | - /* Fill the written data into REG_0D & REG_0E */ |
1916 | - iow(db, DM9000_EPDRL, value); |
1917 | - iow(db, DM9000_EPDRH, value >> 8); |
1918 | - |
1919 | - iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW); /* Issue phyxcer write command */ |
1920 | - |
1921 | - writeb(reg_save, db->io_addr); |
1922 | - spin_unlock_irqrestore(&db->lock, flags); |
1923 | - |
1924 | - dm9000_msleep(db, 1); /* Wait write complete */ |
1925 | - |
1926 | - spin_lock_irqsave(&db->lock,flags); |
1927 | - reg_save = readb(db->io_addr); |
1928 | - |
1929 | - iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */ |
1930 | - |
1931 | - /* restore the previous address */ |
1932 | - writeb(reg_save, db->io_addr); |
1933 | - |
1934 | - spin_unlock_irqrestore(&db->lock, flags); |
1935 | - mutex_unlock(&db->addr_lock); |
1936 | -} |
1937 | - |
1938 | static void |
1939 | dm9000_shutdown(struct net_device *dev) |
1940 | { |
1941 | @@ -1501,7 +1502,12 @@ dm9000_probe(struct platform_device *pdev) |
1942 | db->flags |= DM9000_PLATF_SIMPLE_PHY; |
1943 | #endif |
1944 | |
1945 | - dm9000_reset(db); |
1946 | + /* Fixing bug on dm9000_probe, takeover dm9000_reset(db), |
1947 | + * Need 'NCR_MAC_LBK' bit to indeed stable our DM9000 fifo |
1948 | + * while probe stage. |
1949 | + */ |
1950 | + |
1951 | + iow(db, DM9000_NCR, NCR_MAC_LBK | NCR_RST); |
1952 | |
1953 | /* try multiple times, DM9000 sometimes gets the read wrong */ |
1954 | for (i = 0; i < 8; i++) { |
1955 | diff --git a/drivers/net/ethernet/davicom/dm9000.h b/drivers/net/ethernet/davicom/dm9000.h |
1956 | index 55688bd..9ce058a 100644 |
1957 | --- a/drivers/net/ethernet/davicom/dm9000.h |
1958 | +++ b/drivers/net/ethernet/davicom/dm9000.h |
1959 | @@ -69,7 +69,9 @@ |
1960 | #define NCR_WAKEEN (1<<6) |
1961 | #define NCR_FCOL (1<<4) |
1962 | #define NCR_FDX (1<<3) |
1963 | -#define NCR_LBK (3<<1) |
1964 | + |
1965 | +#define NCR_RESERVED (3<<1) |
1966 | +#define NCR_MAC_LBK (1<<1) |
1967 | #define NCR_RST (1<<0) |
1968 | |
1969 | #define NSR_SPEED (1<<7) |
1970 | @@ -167,5 +169,12 @@ |
1971 | #define ISR_LNKCHNG (1<<5) |
1972 | #define ISR_UNDERRUN (1<<4) |
1973 | |
1974 | +/* Davicom MII registers. |
1975 | + */ |
1976 | + |
1977 | +#define MII_DM_DSPCR 0x1b /* DSP Control Register */ |
1978 | + |
1979 | +#define DSPCR_INIT_PARAM 0xE100 /* DSP init parameter */ |
1980 | + |
1981 | #endif /* _DM9000X_H_ */ |
1982 | |
1983 | diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c |
1984 | index c40526c..547c9f1 100644 |
1985 | --- a/drivers/net/ethernet/freescale/fec_ptp.c |
1986 | +++ b/drivers/net/ethernet/freescale/fec_ptp.c |
1987 | @@ -128,6 +128,7 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev) |
1988 | |
1989 | spin_unlock_irqrestore(&fep->tmreg_lock, flags); |
1990 | } |
1991 | +EXPORT_SYMBOL(fec_ptp_start_cyclecounter); |
1992 | |
1993 | /** |
1994 | * fec_ptp_adjfreq - adjust ptp cycle frequency |
1995 | @@ -318,6 +319,7 @@ int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) |
1996 | return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? |
1997 | -EFAULT : 0; |
1998 | } |
1999 | +EXPORT_SYMBOL(fec_ptp_ioctl); |
2000 | |
2001 | /** |
2002 | * fec_time_keep - call timecounter_read every second to avoid timer overrun |
2003 | @@ -381,3 +383,4 @@ void fec_ptp_init(struct net_device *ndev, struct platform_device *pdev) |
2004 | pr_info("registered PHC device on %s\n", ndev->name); |
2005 | } |
2006 | } |
2007 | +EXPORT_SYMBOL(fec_ptp_init); |
2008 | diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c |
2009 | index 3269eb3..d23dc5e 100644 |
2010 | --- a/drivers/net/ethernet/marvell/sky2.c |
2011 | +++ b/drivers/net/ethernet/marvell/sky2.c |
2012 | @@ -1067,7 +1067,7 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 space) |
2013 | sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp); |
2014 | sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2); |
2015 | |
2016 | - tp = space - 2048/8; |
2017 | + tp = space - 8192/8; |
2018 | sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp); |
2019 | sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4); |
2020 | } else { |
2021 | diff --git a/drivers/net/ethernet/marvell/sky2.h b/drivers/net/ethernet/marvell/sky2.h |
2022 | index 615ac63..ec6dcd8 100644 |
2023 | --- a/drivers/net/ethernet/marvell/sky2.h |
2024 | +++ b/drivers/net/ethernet/marvell/sky2.h |
2025 | @@ -2074,7 +2074,7 @@ enum { |
2026 | GM_IS_RX_FF_OR = 1<<1, /* Receive FIFO Overrun */ |
2027 | GM_IS_RX_COMPL = 1<<0, /* Frame Reception Complete */ |
2028 | |
2029 | -#define GMAC_DEF_MSK GM_IS_TX_FF_UR |
2030 | +#define GMAC_DEF_MSK (GM_IS_TX_FF_UR | GM_IS_RX_FF_OR) |
2031 | }; |
2032 | |
2033 | /* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */ |
2034 | diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c |
2035 | index 286816a..1e42882 100644 |
2036 | --- a/drivers/net/ethernet/micrel/ks8851.c |
2037 | +++ b/drivers/net/ethernet/micrel/ks8851.c |
2038 | @@ -547,7 +547,7 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) |
2039 | for (; rxfc != 0; rxfc--) { |
2040 | rxh = ks8851_rdreg32(ks, KS_RXFHSR); |
2041 | rxstat = rxh & 0xffff; |
2042 | - rxlen = rxh >> 16; |
2043 | + rxlen = (rxh >> 16) & 0xfff; |
2044 | |
2045 | netif_dbg(ks, rx_status, ks->netdev, |
2046 | "rx: stat 0x%04x, len 0x%04x\n", rxstat, rxlen); |
2047 | diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c |
2048 | index 39ab4d0..73ce7dd 100644 |
2049 | --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c |
2050 | +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c |
2051 | @@ -1726,9 +1726,9 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, |
2052 | |
2053 | skb->protocol = eth_type_trans(skb, netdev); |
2054 | if (tcp_ip_status & PCH_GBE_RXD_ACC_STAT_TCPIPOK) |
2055 | - skb->ip_summed = CHECKSUM_NONE; |
2056 | - else |
2057 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
2058 | + else |
2059 | + skb->ip_summed = CHECKSUM_NONE; |
2060 | |
2061 | napi_gro_receive(&adapter->napi, skb); |
2062 | (*work_done)++; |
2063 | diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c |
2064 | index 40aff68..3b1be52 100644 |
2065 | --- a/drivers/net/ethernet/ti/cpsw.c |
2066 | +++ b/drivers/net/ethernet/ti/cpsw.c |
2067 | @@ -375,7 +375,7 @@ void cpsw_tx_handler(void *token, int len, int status) |
2068 | struct cpsw_priv *priv = netdev_priv(ndev); |
2069 | |
2070 | if (unlikely(netif_queue_stopped(ndev))) |
2071 | - netif_start_queue(ndev); |
2072 | + netif_wake_queue(ndev); |
2073 | cpts_tx_timestamp(&priv->cpts, skb); |
2074 | priv->stats.tx_packets++; |
2075 | priv->stats.tx_bytes += len; |
2076 | @@ -1111,7 +1111,7 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, |
2077 | struct platform_device *mdio; |
2078 | |
2079 | parp = of_get_property(slave_node, "phy_id", &lenp); |
2080 | - if ((parp == NULL) && (lenp != (sizeof(void *) * 2))) { |
2081 | + if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) { |
2082 | pr_err("Missing slave[%d] phy_id property\n", i); |
2083 | ret = -EINVAL; |
2084 | goto error_ret; |
2085 | diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c |
2086 | index 2a3e2c5..4ebcb24 100644 |
2087 | --- a/drivers/net/ethernet/ti/davinci_emac.c |
2088 | +++ b/drivers/net/ethernet/ti/davinci_emac.c |
2089 | @@ -1055,7 +1055,7 @@ static void emac_tx_handler(void *token, int len, int status) |
2090 | atomic_dec(&priv->cur_tx); |
2091 | |
2092 | if (unlikely(netif_queue_stopped(ndev))) |
2093 | - netif_start_queue(ndev); |
2094 | + netif_wake_queue(ndev); |
2095 | ndev->stats.tx_packets++; |
2096 | ndev->stats.tx_bytes += len; |
2097 | dev_kfree_skb_any(skb); |
2098 | diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c |
2099 | index 251a335..937c09d 100644 |
2100 | --- a/drivers/net/usb/smsc75xx.c |
2101 | +++ b/drivers/net/usb/smsc75xx.c |
2102 | @@ -914,8 +914,12 @@ static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size) |
2103 | static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu) |
2104 | { |
2105 | struct usbnet *dev = netdev_priv(netdev); |
2106 | + int ret; |
2107 | + |
2108 | + if (new_mtu > MAX_SINGLE_PACKET_SIZE) |
2109 | + return -EINVAL; |
2110 | |
2111 | - int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu); |
2112 | + ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu + ETH_HLEN); |
2113 | if (ret < 0) { |
2114 | netdev_warn(dev->net, "Failed to set mac rx frame length\n"); |
2115 | return ret; |
2116 | @@ -1324,7 +1328,7 @@ static int smsc75xx_reset(struct usbnet *dev) |
2117 | |
2118 | netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x\n", buf); |
2119 | |
2120 | - ret = smsc75xx_set_rx_max_frame_length(dev, 1514); |
2121 | + ret = smsc75xx_set_rx_max_frame_length(dev, dev->net->mtu + ETH_HLEN); |
2122 | if (ret < 0) { |
2123 | netdev_warn(dev->net, "Failed to set max rx frame length\n"); |
2124 | return ret; |
2125 | @@ -2136,8 +2140,8 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
2126 | else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT)) |
2127 | dev->net->stats.rx_frame_errors++; |
2128 | } else { |
2129 | - /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */ |
2130 | - if (unlikely(size > (ETH_FRAME_LEN + 12))) { |
2131 | + /* MAX_SINGLE_PACKET_SIZE + 4(CRC) + 2(COE) + 4(Vlan) */ |
2132 | + if (unlikely(size > (MAX_SINGLE_PACKET_SIZE + ETH_HLEN + 12))) { |
2133 | netif_dbg(dev, rx_err, dev->net, |
2134 | "size err rx_cmd_a=0x%08x\n", |
2135 | rx_cmd_a); |
2136 | diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c |
2137 | index 56317b0..e99f481 100644 |
2138 | --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c |
2139 | +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c |
2140 | @@ -976,6 +976,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, |
2141 | AR_PHY_CL_TAB_1, |
2142 | AR_PHY_CL_TAB_2 }; |
2143 | |
2144 | + /* Use chip chainmask only for calibration */ |
2145 | ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); |
2146 | |
2147 | if (rtt) { |
2148 | @@ -1131,6 +1132,9 @@ skip_tx_iqcal: |
2149 | ar9003_hw_rtt_disable(ah); |
2150 | } |
2151 | |
2152 | + /* Revert chainmask to runtime parameters */ |
2153 | + ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); |
2154 | + |
2155 | /* Initialize list pointers */ |
2156 | ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; |
2157 | ah->supp_cals = IQ_MISMATCH_CAL; |
2158 | diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c |
2159 | index ade3afb..7fdac6c 100644 |
2160 | --- a/drivers/net/wireless/ath/ath9k/link.c |
2161 | +++ b/drivers/net/wireless/ath/ath9k/link.c |
2162 | @@ -28,21 +28,21 @@ void ath_tx_complete_poll_work(struct work_struct *work) |
2163 | int i; |
2164 | bool needreset = false; |
2165 | |
2166 | - for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) |
2167 | - if (ATH_TXQ_SETUP(sc, i)) { |
2168 | - txq = &sc->tx.txq[i]; |
2169 | - ath_txq_lock(sc, txq); |
2170 | - if (txq->axq_depth) { |
2171 | - if (txq->axq_tx_inprogress) { |
2172 | - needreset = true; |
2173 | - ath_txq_unlock(sc, txq); |
2174 | - break; |
2175 | - } else { |
2176 | - txq->axq_tx_inprogress = true; |
2177 | - } |
2178 | + for (i = 0; i < IEEE80211_NUM_ACS; i++) { |
2179 | + txq = sc->tx.txq_map[i]; |
2180 | + |
2181 | + ath_txq_lock(sc, txq); |
2182 | + if (txq->axq_depth) { |
2183 | + if (txq->axq_tx_inprogress) { |
2184 | + needreset = true; |
2185 | + ath_txq_unlock(sc, txq); |
2186 | + break; |
2187 | + } else { |
2188 | + txq->axq_tx_inprogress = true; |
2189 | } |
2190 | - ath_txq_unlock_complete(sc, txq); |
2191 | } |
2192 | + ath_txq_unlock_complete(sc, txq); |
2193 | + } |
2194 | |
2195 | if (needreset) { |
2196 | ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, |
2197 | @@ -170,7 +170,8 @@ void ath_rx_poll(unsigned long data) |
2198 | { |
2199 | struct ath_softc *sc = (struct ath_softc *)data; |
2200 | |
2201 | - ieee80211_queue_work(sc->hw, &sc->hw_check_work); |
2202 | + if (!test_bit(SC_OP_INVALID, &sc->sc_flags)) |
2203 | + ieee80211_queue_work(sc->hw, &sc->hw_check_work); |
2204 | } |
2205 | |
2206 | /* |
2207 | diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c |
2208 | index 38bc5a7..1221469 100644 |
2209 | --- a/drivers/net/wireless/b43/dma.c |
2210 | +++ b/drivers/net/wireless/b43/dma.c |
2211 | @@ -1487,8 +1487,12 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, |
2212 | const struct b43_dma_ops *ops; |
2213 | struct b43_dmaring *ring; |
2214 | struct b43_dmadesc_meta *meta; |
2215 | + static const struct b43_txstatus fake; /* filled with 0 */ |
2216 | + const struct b43_txstatus *txstat; |
2217 | int slot, firstused; |
2218 | bool frame_succeed; |
2219 | + int skip; |
2220 | + static u8 err_out1, err_out2; |
2221 | |
2222 | ring = parse_cookie(dev, status->cookie, &slot); |
2223 | if (unlikely(!ring)) |
2224 | @@ -1501,13 +1505,36 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, |
2225 | firstused = ring->current_slot - ring->used_slots + 1; |
2226 | if (firstused < 0) |
2227 | firstused = ring->nr_slots + firstused; |
2228 | + |
2229 | + skip = 0; |
2230 | if (unlikely(slot != firstused)) { |
2231 | /* This possibly is a firmware bug and will result in |
2232 | - * malfunction, memory leaks and/or stall of DMA functionality. */ |
2233 | - b43dbg(dev->wl, "Out of order TX status report on DMA ring %d. " |
2234 | - "Expected %d, but got %d\n", |
2235 | - ring->index, firstused, slot); |
2236 | - return; |
2237 | + * malfunction, memory leaks and/or stall of DMA functionality. |
2238 | + */ |
2239 | + if (slot == next_slot(ring, next_slot(ring, firstused))) { |
2240 | + /* If a single header/data pair was missed, skip over |
2241 | + * the first two slots in an attempt to recover. |
2242 | + */ |
2243 | + slot = firstused; |
2244 | + skip = 2; |
2245 | + if (!err_out1) { |
2246 | + /* Report the error once. */ |
2247 | + b43dbg(dev->wl, |
2248 | + "Skip on DMA ring %d slot %d.\n", |
2249 | + ring->index, slot); |
2250 | + err_out1 = 1; |
2251 | + } |
2252 | + } else { |
2253 | + /* More than a single header/data pair were missed. |
2254 | + * Report this error once. |
2255 | + */ |
2256 | + if (!err_out2) |
2257 | + b43dbg(dev->wl, |
2258 | + "Out of order TX status report on DMA ring %d. Expected %d, but got %d\n", |
2259 | + ring->index, firstused, slot); |
2260 | + err_out2 = 1; |
2261 | + return; |
2262 | + } |
2263 | } |
2264 | |
2265 | ops = ring->ops; |
2266 | @@ -1522,11 +1549,13 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, |
2267 | slot, firstused, ring->index); |
2268 | break; |
2269 | } |
2270 | + |
2271 | if (meta->skb) { |
2272 | struct b43_private_tx_info *priv_info = |
2273 | - b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb)); |
2274 | + b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb)); |
2275 | |
2276 | - unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1); |
2277 | + unmap_descbuffer(ring, meta->dmaaddr, |
2278 | + meta->skb->len, 1); |
2279 | kfree(priv_info->bouncebuffer); |
2280 | priv_info->bouncebuffer = NULL; |
2281 | } else { |
2282 | @@ -1538,8 +1567,9 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, |
2283 | struct ieee80211_tx_info *info; |
2284 | |
2285 | if (unlikely(!meta->skb)) { |
2286 | - /* This is a scatter-gather fragment of a frame, so |
2287 | - * the skb pointer must not be NULL. */ |
2288 | + /* This is a scatter-gather fragment of a frame, |
2289 | + * so the skb pointer must not be NULL. |
2290 | + */ |
2291 | b43dbg(dev->wl, "TX status unexpected NULL skb " |
2292 | "at slot %d (first=%d) on ring %d\n", |
2293 | slot, firstused, ring->index); |
2294 | @@ -1550,9 +1580,18 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, |
2295 | |
2296 | /* |
2297 | * Call back to inform the ieee80211 subsystem about |
2298 | - * the status of the transmission. |
2299 | + * the status of the transmission. When skipping over |
2300 | + * a missed TX status report, use a status structure |
2301 | + * filled with zeros to indicate that the frame was not |
2302 | + * sent (frame_count 0) and not acknowledged |
2303 | */ |
2304 | - frame_succeed = b43_fill_txstatus_report(dev, info, status); |
2305 | + if (unlikely(skip)) |
2306 | + txstat = &fake; |
2307 | + else |
2308 | + txstat = status; |
2309 | + |
2310 | + frame_succeed = b43_fill_txstatus_report(dev, info, |
2311 | + txstat); |
2312 | #ifdef CONFIG_B43_DEBUG |
2313 | if (frame_succeed) |
2314 | ring->nr_succeed_tx_packets++; |
2315 | @@ -1580,12 +1619,14 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, |
2316 | /* Everything unmapped and free'd. So it's not used anymore. */ |
2317 | ring->used_slots--; |
2318 | |
2319 | - if (meta->is_last_fragment) { |
2320 | + if (meta->is_last_fragment && !skip) { |
2321 | /* This is the last scatter-gather |
2322 | * fragment of the frame. We are done. */ |
2323 | break; |
2324 | } |
2325 | slot = next_slot(ring, slot); |
2326 | + if (skip > 0) |
2327 | + --skip; |
2328 | } |
2329 | if (ring->stopped) { |
2330 | B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME); |
2331 | diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c |
2332 | index 3c35382..e8486c1 100644 |
2333 | --- a/drivers/net/wireless/b43/phy_n.c |
2334 | +++ b/drivers/net/wireless/b43/phy_n.c |
2335 | @@ -1564,7 +1564,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) |
2336 | u16 clip_off[2] = { 0xFFFF, 0xFFFF }; |
2337 | |
2338 | u8 vcm_final = 0; |
2339 | - s8 offset[4]; |
2340 | + s32 offset[4]; |
2341 | s32 results[8][4] = { }; |
2342 | s32 results_min[4] = { }; |
2343 | s32 poll_results[4] = { }; |
2344 | @@ -1615,7 +1615,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) |
2345 | } |
2346 | for (i = 0; i < 4; i += 2) { |
2347 | s32 curr; |
2348 | - s32 mind = 40; |
2349 | + s32 mind = 0x100000; |
2350 | s32 minpoll = 249; |
2351 | u8 minvcm = 0; |
2352 | if (2 * core != i) |
2353 | @@ -1732,7 +1732,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) |
2354 | u8 regs_save_radio[2]; |
2355 | u16 regs_save_phy[2]; |
2356 | |
2357 | - s8 offset[4]; |
2358 | + s32 offset[4]; |
2359 | u8 core; |
2360 | u8 rail; |
2361 | |
2362 | @@ -1799,7 +1799,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) |
2363 | } |
2364 | |
2365 | for (i = 0; i < 4; i++) { |
2366 | - s32 mind = 40; |
2367 | + s32 mind = 0x100000; |
2368 | u8 minvcm = 0; |
2369 | s32 minpoll = 249; |
2370 | s32 curr; |
2371 | diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c |
2372 | index 6ff4660..0348f42 100644 |
2373 | --- a/drivers/net/wireless/iwlwifi/dvm/lib.c |
2374 | +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c |
2375 | @@ -1262,6 +1262,15 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) |
2376 | } |
2377 | |
2378 | /* |
2379 | + * This can happen upon FW ASSERT: we clear the STATUS_FW_ERROR flag |
2380 | + * in iwl_down but cancel the workers only later. |
2381 | + */ |
2382 | + if (!priv->ucode_loaded) { |
2383 | + IWL_ERR(priv, "Fw not loaded - dropping CMD: %x\n", cmd->id); |
2384 | + return -EIO; |
2385 | + } |
2386 | + |
2387 | + /* |
2388 | * Synchronous commands from this op-mode must hold |
2389 | * the mutex, this ensures we don't try to send two |
2390 | * (or more) synchronous commands at a time. |
2391 | diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c |
2392 | index c6467e5..9b138b8 100644 |
2393 | --- a/drivers/net/wireless/iwlwifi/dvm/ucode.c |
2394 | +++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c |
2395 | @@ -450,6 +450,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, |
2396 | return -EIO; |
2397 | } |
2398 | |
2399 | + priv->ucode_loaded = true; |
2400 | + |
2401 | /* |
2402 | * This step takes a long time (60-80ms!!) and |
2403 | * WoWLAN image should be loaded quickly, so |
2404 | @@ -474,8 +476,6 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, |
2405 | return ret; |
2406 | } |
2407 | |
2408 | - priv->ucode_loaded = true; |
2409 | - |
2410 | return 0; |
2411 | } |
2412 | |
2413 | diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c |
2414 | index c6cd922..d760da9 100644 |
2415 | --- a/drivers/net/wireless/iwlwifi/pcie/tx.c |
2416 | +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c |
2417 | @@ -1242,7 +1242,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, |
2418 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { |
2419 | int copy = 0; |
2420 | |
2421 | - if (!cmd->len) |
2422 | + if (!cmd->len[i]) |
2423 | continue; |
2424 | |
2425 | /* need at least IWL_HCMD_MIN_COPY_SIZE copied */ |
2426 | diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c |
2427 | index 5f438e6..bc9a402 100644 |
2428 | --- a/drivers/net/wireless/mwifiex/cmdevt.c |
2429 | +++ b/drivers/net/wireless/mwifiex/cmdevt.c |
2430 | @@ -156,6 +156,20 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, |
2431 | return -1; |
2432 | } |
2433 | |
2434 | + cmd_code = le16_to_cpu(host_cmd->command); |
2435 | + cmd_size = le16_to_cpu(host_cmd->size); |
2436 | + |
2437 | + if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET && |
2438 | + cmd_code != HostCmd_CMD_FUNC_SHUTDOWN && |
2439 | + cmd_code != HostCmd_CMD_FUNC_INIT) { |
2440 | + dev_err(adapter->dev, |
2441 | + "DNLD_CMD: FW in reset state, ignore cmd %#x\n", |
2442 | + cmd_code); |
2443 | + mwifiex_complete_cmd(adapter, cmd_node); |
2444 | + mwifiex_insert_cmd_to_free_q(adapter, cmd_node); |
2445 | + return -1; |
2446 | + } |
2447 | + |
2448 | /* Set command sequence number */ |
2449 | adapter->seq_num++; |
2450 | host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO |
2451 | @@ -167,9 +181,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, |
2452 | adapter->curr_cmd = cmd_node; |
2453 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); |
2454 | |
2455 | - cmd_code = le16_to_cpu(host_cmd->command); |
2456 | - cmd_size = le16_to_cpu(host_cmd->size); |
2457 | - |
2458 | /* Adjust skb length */ |
2459 | if (cmd_node->cmd_skb->len > cmd_size) |
2460 | /* |
2461 | @@ -488,8 +499,6 @@ int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no, |
2462 | |
2463 | ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid, |
2464 | data_buf); |
2465 | - if (!ret) |
2466 | - ret = mwifiex_wait_queue_complete(adapter); |
2467 | |
2468 | return ret; |
2469 | } |
2470 | @@ -592,9 +601,10 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, |
2471 | if (cmd_no == HostCmd_CMD_802_11_SCAN) { |
2472 | mwifiex_queue_scan_cmd(priv, cmd_node); |
2473 | } else { |
2474 | - adapter->cmd_queued = cmd_node; |
2475 | mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); |
2476 | queue_work(adapter->workqueue, &adapter->main_work); |
2477 | + if (cmd_node->wait_q_enabled) |
2478 | + ret = mwifiex_wait_queue_complete(adapter, cmd_node); |
2479 | } |
2480 | |
2481 | return ret; |
2482 | diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c |
2483 | index 39f03ce..78c3aa6 100644 |
2484 | --- a/drivers/net/wireless/mwifiex/init.c |
2485 | +++ b/drivers/net/wireless/mwifiex/init.c |
2486 | @@ -707,6 +707,14 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) |
2487 | return ret; |
2488 | } |
2489 | |
2490 | + /* cancel current command */ |
2491 | + if (adapter->curr_cmd) { |
2492 | + dev_warn(adapter->dev, "curr_cmd is still in processing\n"); |
2493 | + del_timer(&adapter->cmd_timer); |
2494 | + mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); |
2495 | + adapter->curr_cmd = NULL; |
2496 | + } |
2497 | + |
2498 | /* shut down mwifiex */ |
2499 | dev_dbg(adapter->dev, "info: shutdown mwifiex...\n"); |
2500 | |
2501 | diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h |
2502 | index 1b3cfc8..db39449 100644 |
2503 | --- a/drivers/net/wireless/mwifiex/main.h |
2504 | +++ b/drivers/net/wireless/mwifiex/main.h |
2505 | @@ -714,7 +714,6 @@ struct mwifiex_adapter { |
2506 | u16 cmd_wait_q_required; |
2507 | struct mwifiex_wait_queue cmd_wait_q; |
2508 | u8 scan_wait_q_woken; |
2509 | - struct cmd_ctrl_node *cmd_queued; |
2510 | spinlock_t queue_lock; /* lock for tx queues */ |
2511 | struct completion fw_load; |
2512 | u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; |
2513 | @@ -994,7 +993,8 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, |
2514 | struct mwifiex_multicast_list *mcast_list); |
2515 | int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, |
2516 | struct net_device *dev); |
2517 | -int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); |
2518 | +int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter, |
2519 | + struct cmd_ctrl_node *cmd_queued); |
2520 | int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, |
2521 | struct cfg80211_ssid *req_ssid); |
2522 | int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); |
2523 | diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c |
2524 | index 973a9d9..8955a0e 100644 |
2525 | --- a/drivers/net/wireless/mwifiex/scan.c |
2526 | +++ b/drivers/net/wireless/mwifiex/scan.c |
2527 | @@ -1366,10 +1366,13 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, |
2528 | list_del(&cmd_node->list); |
2529 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, |
2530 | flags); |
2531 | - adapter->cmd_queued = cmd_node; |
2532 | mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, |
2533 | true); |
2534 | queue_work(adapter->workqueue, &adapter->main_work); |
2535 | + |
2536 | + /* Perform internal scan synchronously */ |
2537 | + if (!priv->scan_request) |
2538 | + mwifiex_wait_queue_complete(adapter, cmd_node); |
2539 | } else { |
2540 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, |
2541 | flags); |
2542 | @@ -1923,9 +1926,6 @@ int mwifiex_request_scan(struct mwifiex_private *priv, |
2543 | /* Normal scan */ |
2544 | ret = mwifiex_scan_networks(priv, NULL); |
2545 | |
2546 | - if (!ret) |
2547 | - ret = mwifiex_wait_queue_complete(priv->adapter); |
2548 | - |
2549 | up(&priv->async_sem); |
2550 | |
2551 | return ret; |
2552 | diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c |
2553 | index f542bb8..1798bc7 100644 |
2554 | --- a/drivers/net/wireless/mwifiex/sta_ioctl.c |
2555 | +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c |
2556 | @@ -54,16 +54,10 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, |
2557 | * This function waits on a cmd wait queue. It also cancels the pending |
2558 | * request after waking up, in case of errors. |
2559 | */ |
2560 | -int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) |
2561 | +int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter, |
2562 | + struct cmd_ctrl_node *cmd_queued) |
2563 | { |
2564 | int status; |
2565 | - struct cmd_ctrl_node *cmd_queued; |
2566 | - |
2567 | - if (!adapter->cmd_queued) |
2568 | - return 0; |
2569 | - |
2570 | - cmd_queued = adapter->cmd_queued; |
2571 | - adapter->cmd_queued = NULL; |
2572 | |
2573 | dev_dbg(adapter->dev, "cmd pending\n"); |
2574 | atomic_inc(&adapter->cmd_pending); |
2575 | diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c |
2576 | index 2106fcf..82bc684 100644 |
2577 | --- a/drivers/net/wireless/rtlwifi/usb.c |
2578 | +++ b/drivers/net/wireless/rtlwifi/usb.c |
2579 | @@ -854,6 +854,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, |
2580 | if (unlikely(!_urb)) { |
2581 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, |
2582 | "Can't allocate urb. Drop skb!\n"); |
2583 | + kfree_skb(skb); |
2584 | return; |
2585 | } |
2586 | urb_list = &rtlusb->tx_pending[ep_num]; |
2587 | diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c |
2588 | index 2785843..5a0f54a 100644 |
2589 | --- a/drivers/regulator/core.c |
2590 | +++ b/drivers/regulator/core.c |
2591 | @@ -200,8 +200,8 @@ static int regulator_check_consumers(struct regulator_dev *rdev, |
2592 | } |
2593 | |
2594 | if (*min_uV > *max_uV) { |
2595 | - dev_err(regulator->dev, "Restricting voltage, %u-%uuV\n", |
2596 | - regulator->min_uV, regulator->max_uV); |
2597 | + rdev_err(rdev, "Restricting voltage, %u-%uuV\n", |
2598 | + *min_uV, *max_uV); |
2599 | return -EINVAL; |
2600 | } |
2601 | |
2602 | diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c |
2603 | index 6dc1d28..5b65b52 100644 |
2604 | --- a/drivers/staging/comedi/drivers/s626.c |
2605 | +++ b/drivers/staging/comedi/drivers/s626.c |
2606 | @@ -1482,7 +1482,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) |
2607 | case TRIG_NONE: |
2608 | /* continous acquisition */ |
2609 | devpriv->ai_continous = 1; |
2610 | - devpriv->ai_sample_count = 0; |
2611 | + devpriv->ai_sample_count = 1; |
2612 | break; |
2613 | } |
2614 | |
2615 | diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c |
2616 | index bd587b7..fcf880f 100644 |
2617 | --- a/drivers/target/target_core_transport.c |
2618 | +++ b/drivers/target/target_core_transport.c |
2619 | @@ -1136,8 +1136,10 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb) |
2620 | return ret; |
2621 | |
2622 | ret = target_check_reservation(cmd); |
2623 | - if (ret) |
2624 | + if (ret) { |
2625 | + cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; |
2626 | return ret; |
2627 | + } |
2628 | |
2629 | ret = dev->transport->parse_cdb(cmd); |
2630 | if (ret) |
2631 | diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c |
2632 | index 922e85a..2d2288d 100644 |
2633 | --- a/drivers/tty/serial/atmel_serial.c |
2634 | +++ b/drivers/tty/serial/atmel_serial.c |
2635 | @@ -158,7 +158,7 @@ struct atmel_uart_port { |
2636 | }; |
2637 | |
2638 | static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; |
2639 | -static unsigned long atmel_ports_in_use; |
2640 | +static DECLARE_BITMAP(atmel_ports_in_use, ATMEL_MAX_UART); |
2641 | |
2642 | #ifdef SUPPORT_SYSRQ |
2643 | static struct console atmel_console; |
2644 | @@ -1768,15 +1768,14 @@ static int atmel_serial_probe(struct platform_device *pdev) |
2645 | if (ret < 0) |
2646 | /* port id not found in platform data nor device-tree aliases: |
2647 | * auto-enumerate it */ |
2648 | - ret = find_first_zero_bit(&atmel_ports_in_use, |
2649 | - sizeof(atmel_ports_in_use)); |
2650 | + ret = find_first_zero_bit(atmel_ports_in_use, ATMEL_MAX_UART); |
2651 | |
2652 | - if (ret > ATMEL_MAX_UART) { |
2653 | + if (ret >= ATMEL_MAX_UART) { |
2654 | ret = -ENODEV; |
2655 | goto err; |
2656 | } |
2657 | |
2658 | - if (test_and_set_bit(ret, &atmel_ports_in_use)) { |
2659 | + if (test_and_set_bit(ret, atmel_ports_in_use)) { |
2660 | /* port already in use */ |
2661 | ret = -EBUSY; |
2662 | goto err; |
2663 | @@ -1856,7 +1855,7 @@ static int atmel_serial_remove(struct platform_device *pdev) |
2664 | |
2665 | /* "port" is allocated statically, so we shouldn't free it */ |
2666 | |
2667 | - clear_bit(port->line, &atmel_ports_in_use); |
2668 | + clear_bit(port->line, atmel_ports_in_use); |
2669 | |
2670 | clk_put(atmel_port->clk); |
2671 | |
2672 | diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c |
2673 | index fa7268a..6abb92c 100644 |
2674 | --- a/drivers/tty/vt/vc_screen.c |
2675 | +++ b/drivers/tty/vt/vc_screen.c |
2676 | @@ -93,7 +93,7 @@ vcs_poll_data_free(struct vcs_poll_data *poll) |
2677 | static struct vcs_poll_data * |
2678 | vcs_poll_data_get(struct file *file) |
2679 | { |
2680 | - struct vcs_poll_data *poll = file->private_data; |
2681 | + struct vcs_poll_data *poll = file->private_data, *kill = NULL; |
2682 | |
2683 | if (poll) |
2684 | return poll; |
2685 | @@ -122,10 +122,12 @@ vcs_poll_data_get(struct file *file) |
2686 | file->private_data = poll; |
2687 | } else { |
2688 | /* someone else raced ahead of us */ |
2689 | - vcs_poll_data_free(poll); |
2690 | + kill = poll; |
2691 | poll = file->private_data; |
2692 | } |
2693 | spin_unlock(&file->f_lock); |
2694 | + if (kill) |
2695 | + vcs_poll_data_free(kill); |
2696 | |
2697 | return poll; |
2698 | } |
2699 | diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c |
2700 | index 4d90a80..34a3907 100644 |
2701 | --- a/drivers/usb/gadget/udc-core.c |
2702 | +++ b/drivers/usb/gadget/udc-core.c |
2703 | @@ -265,7 +265,7 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) |
2704 | usb_gadget_disconnect(udc->gadget); |
2705 | udc->driver->disconnect(udc->gadget); |
2706 | udc->driver->unbind(udc->gadget); |
2707 | - usb_gadget_udc_stop(udc->gadget, udc->driver); |
2708 | + usb_gadget_udc_stop(udc->gadget, NULL); |
2709 | } else { |
2710 | usb_gadget_stop(udc->gadget, udc->driver); |
2711 | } |
2712 | diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c |
2713 | index b476daf..010f686 100644 |
2714 | --- a/drivers/usb/host/ehci-sched.c |
2715 | +++ b/drivers/usb/host/ehci-sched.c |
2716 | @@ -1214,6 +1214,7 @@ itd_urb_transaction ( |
2717 | |
2718 | memset (itd, 0, sizeof *itd); |
2719 | itd->itd_dma = itd_dma; |
2720 | + itd->frame = 9999; /* an invalid value */ |
2721 | list_add (&itd->itd_list, &sched->td_list); |
2722 | } |
2723 | spin_unlock_irqrestore (&ehci->lock, flags); |
2724 | @@ -1915,6 +1916,7 @@ sitd_urb_transaction ( |
2725 | |
2726 | memset (sitd, 0, sizeof *sitd); |
2727 | sitd->sitd_dma = sitd_dma; |
2728 | + sitd->frame = 9999; /* an invalid value */ |
2729 | list_add (&sitd->sitd_list, &iso_sched->td_list); |
2730 | } |
2731 | |
2732 | diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c |
2733 | index 7f76a49..f2845f1 100644 |
2734 | --- a/drivers/usb/host/xhci-ring.c |
2735 | +++ b/drivers/usb/host/xhci-ring.c |
2736 | @@ -2027,8 +2027,8 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, |
2737 | if (event_trb != ep_ring->dequeue && |
2738 | event_trb != td->last_trb) |
2739 | td->urb->actual_length = |
2740 | - td->urb->transfer_buffer_length |
2741 | - - TRB_LEN(le32_to_cpu(event->transfer_len)); |
2742 | + td->urb->transfer_buffer_length - |
2743 | + EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
2744 | else |
2745 | td->urb->actual_length = 0; |
2746 | |
2747 | @@ -2060,7 +2060,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, |
2748 | /* Maybe the event was for the data stage? */ |
2749 | td->urb->actual_length = |
2750 | td->urb->transfer_buffer_length - |
2751 | - TRB_LEN(le32_to_cpu(event->transfer_len)); |
2752 | + EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
2753 | xhci_dbg(xhci, "Waiting for status " |
2754 | "stage event\n"); |
2755 | return 0; |
2756 | @@ -2096,7 +2096,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, |
2757 | /* handle completion code */ |
2758 | switch (trb_comp_code) { |
2759 | case COMP_SUCCESS: |
2760 | - if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) { |
2761 | + if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) { |
2762 | frame->status = 0; |
2763 | break; |
2764 | } |
2765 | @@ -2141,7 +2141,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, |
2766 | len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])); |
2767 | } |
2768 | len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - |
2769 | - TRB_LEN(le32_to_cpu(event->transfer_len)); |
2770 | + EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
2771 | |
2772 | if (trb_comp_code != COMP_STOP_INVAL) { |
2773 | frame->actual_length = len; |
2774 | @@ -2199,7 +2199,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, |
2775 | case COMP_SUCCESS: |
2776 | /* Double check that the HW transferred everything. */ |
2777 | if (event_trb != td->last_trb || |
2778 | - TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { |
2779 | + EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { |
2780 | xhci_warn(xhci, "WARN Successful completion " |
2781 | "on short TX\n"); |
2782 | if (td->urb->transfer_flags & URB_SHORT_NOT_OK) |
2783 | @@ -2227,18 +2227,18 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, |
2784 | "%d bytes untransferred\n", |
2785 | td->urb->ep->desc.bEndpointAddress, |
2786 | td->urb->transfer_buffer_length, |
2787 | - TRB_LEN(le32_to_cpu(event->transfer_len))); |
2788 | + EVENT_TRB_LEN(le32_to_cpu(event->transfer_len))); |
2789 | /* Fast path - was this the last TRB in the TD for this URB? */ |
2790 | if (event_trb == td->last_trb) { |
2791 | - if (TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { |
2792 | + if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { |
2793 | td->urb->actual_length = |
2794 | td->urb->transfer_buffer_length - |
2795 | - TRB_LEN(le32_to_cpu(event->transfer_len)); |
2796 | + EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
2797 | if (td->urb->transfer_buffer_length < |
2798 | td->urb->actual_length) { |
2799 | xhci_warn(xhci, "HC gave bad length " |
2800 | "of %d bytes left\n", |
2801 | - TRB_LEN(le32_to_cpu(event->transfer_len))); |
2802 | + EVENT_TRB_LEN(le32_to_cpu(event->transfer_len))); |
2803 | td->urb->actual_length = 0; |
2804 | if (td->urb->transfer_flags & URB_SHORT_NOT_OK) |
2805 | *status = -EREMOTEIO; |
2806 | @@ -2280,7 +2280,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, |
2807 | if (trb_comp_code != COMP_STOP_INVAL) |
2808 | td->urb->actual_length += |
2809 | TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - |
2810 | - TRB_LEN(le32_to_cpu(event->transfer_len)); |
2811 | + EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
2812 | } |
2813 | |
2814 | return finish_td(xhci, td, event_trb, event, ep, status, false); |
2815 | @@ -2368,7 +2368,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, |
2816 | * transfer type |
2817 | */ |
2818 | case COMP_SUCCESS: |
2819 | - if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) |
2820 | + if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) |
2821 | break; |
2822 | if (xhci->quirks & XHCI_TRUST_TX_LENGTH) |
2823 | trb_comp_code = COMP_SHORT_TX; |
2824 | diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h |
2825 | index 2c510e4..6a563ef 100644 |
2826 | --- a/drivers/usb/host/xhci.h |
2827 | +++ b/drivers/usb/host/xhci.h |
2828 | @@ -972,6 +972,10 @@ struct xhci_transfer_event { |
2829 | __le32 flags; |
2830 | }; |
2831 | |
2832 | +/* Transfer event TRB length bit mask */ |
2833 | +/* bits 0:23 */ |
2834 | +#define EVENT_TRB_LEN(p) ((p) & 0xffffff) |
2835 | + |
2836 | /** Transfer Event bit fields **/ |
2837 | #define TRB_TO_EP_ID(p) (((p) >> 16) & 0x1f) |
2838 | |
2839 | diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c |
2840 | index a88882c..0b44e45 100644 |
2841 | --- a/drivers/usb/serial/ark3116.c |
2842 | +++ b/drivers/usb/serial/ark3116.c |
2843 | @@ -62,7 +62,6 @@ static int is_irda(struct usb_serial *serial) |
2844 | } |
2845 | |
2846 | struct ark3116_private { |
2847 | - wait_queue_head_t delta_msr_wait; |
2848 | struct async_icount icount; |
2849 | int irda; /* 1 for irda device */ |
2850 | |
2851 | @@ -146,7 +145,6 @@ static int ark3116_port_probe(struct usb_serial_port *port) |
2852 | if (!priv) |
2853 | return -ENOMEM; |
2854 | |
2855 | - init_waitqueue_head(&priv->delta_msr_wait); |
2856 | mutex_init(&priv->hw_lock); |
2857 | spin_lock_init(&priv->status_lock); |
2858 | |
2859 | @@ -456,10 +454,14 @@ static int ark3116_ioctl(struct tty_struct *tty, |
2860 | case TIOCMIWAIT: |
2861 | for (;;) { |
2862 | struct async_icount prev = priv->icount; |
2863 | - interruptible_sleep_on(&priv->delta_msr_wait); |
2864 | + interruptible_sleep_on(&port->delta_msr_wait); |
2865 | /* see if a signal did it */ |
2866 | if (signal_pending(current)) |
2867 | return -ERESTARTSYS; |
2868 | + |
2869 | + if (port->serial->disconnected) |
2870 | + return -EIO; |
2871 | + |
2872 | if ((prev.rng == priv->icount.rng) && |
2873 | (prev.dsr == priv->icount.dsr) && |
2874 | (prev.dcd == priv->icount.dcd) && |
2875 | @@ -580,7 +582,7 @@ static void ark3116_update_msr(struct usb_serial_port *port, __u8 msr) |
2876 | priv->icount.dcd++; |
2877 | if (msr & UART_MSR_TERI) |
2878 | priv->icount.rng++; |
2879 | - wake_up_interruptible(&priv->delta_msr_wait); |
2880 | + wake_up_interruptible(&port->delta_msr_wait); |
2881 | } |
2882 | } |
2883 | |
2884 | diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c |
2885 | index d255f66..07d4650 100644 |
2886 | --- a/drivers/usb/serial/ch341.c |
2887 | +++ b/drivers/usb/serial/ch341.c |
2888 | @@ -80,7 +80,6 @@ MODULE_DEVICE_TABLE(usb, id_table); |
2889 | |
2890 | struct ch341_private { |
2891 | spinlock_t lock; /* access lock */ |
2892 | - wait_queue_head_t delta_msr_wait; /* wait queue for modem status */ |
2893 | unsigned baud_rate; /* set baud rate */ |
2894 | u8 line_control; /* set line control value RTS/DTR */ |
2895 | u8 line_status; /* active status of modem control inputs */ |
2896 | @@ -252,7 +251,6 @@ static int ch341_port_probe(struct usb_serial_port *port) |
2897 | return -ENOMEM; |
2898 | |
2899 | spin_lock_init(&priv->lock); |
2900 | - init_waitqueue_head(&priv->delta_msr_wait); |
2901 | priv->baud_rate = DEFAULT_BAUD_RATE; |
2902 | priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; |
2903 | |
2904 | @@ -298,7 +296,7 @@ static void ch341_dtr_rts(struct usb_serial_port *port, int on) |
2905 | priv->line_control &= ~(CH341_BIT_RTS | CH341_BIT_DTR); |
2906 | spin_unlock_irqrestore(&priv->lock, flags); |
2907 | ch341_set_handshake(port->serial->dev, priv->line_control); |
2908 | - wake_up_interruptible(&priv->delta_msr_wait); |
2909 | + wake_up_interruptible(&port->delta_msr_wait); |
2910 | } |
2911 | |
2912 | static void ch341_close(struct usb_serial_port *port) |
2913 | @@ -491,7 +489,7 @@ static void ch341_read_int_callback(struct urb *urb) |
2914 | tty_kref_put(tty); |
2915 | } |
2916 | |
2917 | - wake_up_interruptible(&priv->delta_msr_wait); |
2918 | + wake_up_interruptible(&port->delta_msr_wait); |
2919 | } |
2920 | |
2921 | exit: |
2922 | @@ -517,11 +515,14 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) |
2923 | spin_unlock_irqrestore(&priv->lock, flags); |
2924 | |
2925 | while (!multi_change) { |
2926 | - interruptible_sleep_on(&priv->delta_msr_wait); |
2927 | + interruptible_sleep_on(&port->delta_msr_wait); |
2928 | /* see if a signal did it */ |
2929 | if (signal_pending(current)) |
2930 | return -ERESTARTSYS; |
2931 | |
2932 | + if (port->serial->disconnected) |
2933 | + return -EIO; |
2934 | + |
2935 | spin_lock_irqsave(&priv->lock, flags); |
2936 | status = priv->line_status; |
2937 | multi_change = priv->multi_status_change; |
2938 | diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c |
2939 | index fd8c35f..a06076f 100644 |
2940 | --- a/drivers/usb/serial/cypress_m8.c |
2941 | +++ b/drivers/usb/serial/cypress_m8.c |
2942 | @@ -111,7 +111,6 @@ struct cypress_private { |
2943 | int baud_rate; /* stores current baud rate in |
2944 | integer form */ |
2945 | int isthrottled; /* if throttled, discard reads */ |
2946 | - wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */ |
2947 | char prev_status, diff_status; /* used for TIOCMIWAIT */ |
2948 | /* we pass a pointer to this as the argument sent to |
2949 | cypress_set_termios old_termios */ |
2950 | @@ -449,7 +448,6 @@ static int cypress_generic_port_probe(struct usb_serial_port *port) |
2951 | kfree(priv); |
2952 | return -ENOMEM; |
2953 | } |
2954 | - init_waitqueue_head(&priv->delta_msr_wait); |
2955 | |
2956 | usb_reset_configuration(serial->dev); |
2957 | |
2958 | @@ -868,12 +866,16 @@ static int cypress_ioctl(struct tty_struct *tty, |
2959 | switch (cmd) { |
2960 | /* This code comes from drivers/char/serial.c and ftdi_sio.c */ |
2961 | case TIOCMIWAIT: |
2962 | - while (priv != NULL) { |
2963 | - interruptible_sleep_on(&priv->delta_msr_wait); |
2964 | + for (;;) { |
2965 | + interruptible_sleep_on(&port->delta_msr_wait); |
2966 | /* see if a signal did it */ |
2967 | if (signal_pending(current)) |
2968 | return -ERESTARTSYS; |
2969 | - else { |
2970 | + |
2971 | + if (port->serial->disconnected) |
2972 | + return -EIO; |
2973 | + |
2974 | + { |
2975 | char diff = priv->diff_status; |
2976 | if (diff == 0) |
2977 | return -EIO; /* no change => error */ |
2978 | @@ -1187,7 +1189,7 @@ static void cypress_read_int_callback(struct urb *urb) |
2979 | if (priv->current_status != priv->prev_status) { |
2980 | priv->diff_status |= priv->current_status ^ |
2981 | priv->prev_status; |
2982 | - wake_up_interruptible(&priv->delta_msr_wait); |
2983 | + wake_up_interruptible(&port->delta_msr_wait); |
2984 | priv->prev_status = priv->current_status; |
2985 | } |
2986 | spin_unlock_irqrestore(&priv->lock, flags); |
2987 | diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c |
2988 | index 6e4eb57..1e64343 100644 |
2989 | --- a/drivers/usb/serial/f81232.c |
2990 | +++ b/drivers/usb/serial/f81232.c |
2991 | @@ -47,7 +47,6 @@ MODULE_DEVICE_TABLE(usb, id_table); |
2992 | |
2993 | struct f81232_private { |
2994 | spinlock_t lock; |
2995 | - wait_queue_head_t delta_msr_wait; |
2996 | u8 line_control; |
2997 | u8 line_status; |
2998 | }; |
2999 | @@ -112,7 +111,7 @@ static void f81232_process_read_urb(struct urb *urb) |
3000 | line_status = priv->line_status; |
3001 | priv->line_status &= ~UART_STATE_TRANSIENT_MASK; |
3002 | spin_unlock_irqrestore(&priv->lock, flags); |
3003 | - wake_up_interruptible(&priv->delta_msr_wait); |
3004 | + wake_up_interruptible(&port->delta_msr_wait); |
3005 | |
3006 | if (!urb->actual_length) |
3007 | return; |
3008 | @@ -261,11 +260,14 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) |
3009 | spin_unlock_irqrestore(&priv->lock, flags); |
3010 | |
3011 | while (1) { |
3012 | - interruptible_sleep_on(&priv->delta_msr_wait); |
3013 | + interruptible_sleep_on(&port->delta_msr_wait); |
3014 | /* see if a signal did it */ |
3015 | if (signal_pending(current)) |
3016 | return -ERESTARTSYS; |
3017 | |
3018 | + if (port->serial->disconnected) |
3019 | + return -EIO; |
3020 | + |
3021 | spin_lock_irqsave(&priv->lock, flags); |
3022 | status = priv->line_status; |
3023 | spin_unlock_irqrestore(&priv->lock, flags); |
3024 | @@ -327,7 +329,6 @@ static int f81232_port_probe(struct usb_serial_port *port) |
3025 | return -ENOMEM; |
3026 | |
3027 | spin_lock_init(&priv->lock); |
3028 | - init_waitqueue_head(&priv->delta_msr_wait); |
3029 | |
3030 | usb_set_serial_port_data(port, priv); |
3031 | |
3032 | diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c |
3033 | index d07fccf..8e4f40b 100644 |
3034 | --- a/drivers/usb/serial/ftdi_sio.c |
3035 | +++ b/drivers/usb/serial/ftdi_sio.c |
3036 | @@ -69,9 +69,7 @@ struct ftdi_private { |
3037 | int flags; /* some ASYNC_xxxx flags are supported */ |
3038 | unsigned long last_dtr_rts; /* saved modem control outputs */ |
3039 | struct async_icount icount; |
3040 | - wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ |
3041 | char prev_status; /* Used for TIOCMIWAIT */ |
3042 | - bool dev_gone; /* Used to abort TIOCMIWAIT */ |
3043 | char transmit_empty; /* If transmitter is empty or not */ |
3044 | __u16 interface; /* FT2232C, FT2232H or FT4232H port interface |
3045 | (0 for FT232/245) */ |
3046 | @@ -642,6 +640,7 @@ static struct usb_device_id id_table_combined [] = { |
3047 | { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, |
3048 | { USB_DEVICE(ACTON_VID, ACTON_SPECTRAPRO_PID) }, |
3049 | { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, |
3050 | + { USB_DEVICE(MITSUBISHI_VID, MITSUBISHI_FXUSB_PID) }, |
3051 | { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, |
3052 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, |
3053 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, |
3054 | @@ -1691,10 +1690,8 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) |
3055 | |
3056 | kref_init(&priv->kref); |
3057 | mutex_init(&priv->cfg_lock); |
3058 | - init_waitqueue_head(&priv->delta_msr_wait); |
3059 | |
3060 | priv->flags = ASYNC_LOW_LATENCY; |
3061 | - priv->dev_gone = false; |
3062 | |
3063 | if (quirk && quirk->port_probe) |
3064 | quirk->port_probe(priv); |
3065 | @@ -1840,8 +1837,7 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port) |
3066 | { |
3067 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
3068 | |
3069 | - priv->dev_gone = true; |
3070 | - wake_up_interruptible_all(&priv->delta_msr_wait); |
3071 | + wake_up_interruptible(&port->delta_msr_wait); |
3072 | |
3073 | remove_sysfs_attrs(port); |
3074 | |
3075 | @@ -1990,7 +1986,7 @@ static int ftdi_process_packet(struct tty_struct *tty, |
3076 | if (diff_status & FTDI_RS0_RLSD) |
3077 | priv->icount.dcd++; |
3078 | |
3079 | - wake_up_interruptible_all(&priv->delta_msr_wait); |
3080 | + wake_up_interruptible(&port->delta_msr_wait); |
3081 | priv->prev_status = status; |
3082 | } |
3083 | |
3084 | @@ -2447,11 +2443,15 @@ static int ftdi_ioctl(struct tty_struct *tty, |
3085 | */ |
3086 | case TIOCMIWAIT: |
3087 | cprev = priv->icount; |
3088 | - while (!priv->dev_gone) { |
3089 | - interruptible_sleep_on(&priv->delta_msr_wait); |
3090 | + for (;;) { |
3091 | + interruptible_sleep_on(&port->delta_msr_wait); |
3092 | /* see if a signal did it */ |
3093 | if (signal_pending(current)) |
3094 | return -ERESTARTSYS; |
3095 | + |
3096 | + if (port->serial->disconnected) |
3097 | + return -EIO; |
3098 | + |
3099 | cnow = priv->icount; |
3100 | if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || |
3101 | ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || |
3102 | @@ -2461,8 +2461,6 @@ static int ftdi_ioctl(struct tty_struct *tty, |
3103 | } |
3104 | cprev = cnow; |
3105 | } |
3106 | - return -EIO; |
3107 | - break; |
3108 | case TIOCSERGETLSR: |
3109 | return get_lsr_info(port, (struct serial_struct __user *)arg); |
3110 | break; |
3111 | diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h |
3112 | index 9d359e1..e79861e 100644 |
3113 | --- a/drivers/usb/serial/ftdi_sio_ids.h |
3114 | +++ b/drivers/usb/serial/ftdi_sio_ids.h |
3115 | @@ -584,6 +584,13 @@ |
3116 | #define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ |
3117 | |
3118 | /* |
3119 | + * Mitsubishi Electric Corp. (http://www.meau.com) |
3120 | + * Submitted by Konstantin Holoborodko |
3121 | + */ |
3122 | +#define MITSUBISHI_VID 0x06D3 |
3123 | +#define MITSUBISHI_FXUSB_PID 0x0284 /* USB/RS422 converters: FX-USB-AW/-BD */ |
3124 | + |
3125 | +/* |
3126 | * Definitions for B&B Electronics products. |
3127 | */ |
3128 | #define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ |
3129 | diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c |
3130 | index 7b770c7..adfd73d 100644 |
3131 | --- a/drivers/usb/serial/io_edgeport.c |
3132 | +++ b/drivers/usb/serial/io_edgeport.c |
3133 | @@ -110,7 +110,6 @@ struct edgeport_port { |
3134 | wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ |
3135 | wait_queue_head_t wait_open; /* for handling sleeping while waiting for open to finish */ |
3136 | wait_queue_head_t wait_command; /* for handling sleeping while waiting for command to finish */ |
3137 | - wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ |
3138 | |
3139 | struct async_icount icount; |
3140 | struct usb_serial_port *port; /* loop back to the owner of this object */ |
3141 | @@ -884,7 +883,6 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port) |
3142 | /* initialize our wait queues */ |
3143 | init_waitqueue_head(&edge_port->wait_open); |
3144 | init_waitqueue_head(&edge_port->wait_chase); |
3145 | - init_waitqueue_head(&edge_port->delta_msr_wait); |
3146 | init_waitqueue_head(&edge_port->wait_command); |
3147 | |
3148 | /* initialize our icount structure */ |
3149 | @@ -1669,13 +1667,17 @@ static int edge_ioctl(struct tty_struct *tty, |
3150 | dev_dbg(&port->dev, "%s (%d) TIOCMIWAIT\n", __func__, port->number); |
3151 | cprev = edge_port->icount; |
3152 | while (1) { |
3153 | - prepare_to_wait(&edge_port->delta_msr_wait, |
3154 | + prepare_to_wait(&port->delta_msr_wait, |
3155 | &wait, TASK_INTERRUPTIBLE); |
3156 | schedule(); |
3157 | - finish_wait(&edge_port->delta_msr_wait, &wait); |
3158 | + finish_wait(&port->delta_msr_wait, &wait); |
3159 | /* see if a signal did it */ |
3160 | if (signal_pending(current)) |
3161 | return -ERESTARTSYS; |
3162 | + |
3163 | + if (port->serial->disconnected) |
3164 | + return -EIO; |
3165 | + |
3166 | cnow = edge_port->icount; |
3167 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && |
3168 | cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) |
3169 | @@ -2055,7 +2057,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr) |
3170 | icount->dcd++; |
3171 | if (newMsr & EDGEPORT_MSR_DELTA_RI) |
3172 | icount->rng++; |
3173 | - wake_up_interruptible(&edge_port->delta_msr_wait); |
3174 | + wake_up_interruptible(&edge_port->port->delta_msr_wait); |
3175 | } |
3176 | |
3177 | /* Save the new modem status */ |
3178 | diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c |
3179 | index aa6462f..1db782d 100644 |
3180 | --- a/drivers/usb/serial/io_ti.c |
3181 | +++ b/drivers/usb/serial/io_ti.c |
3182 | @@ -87,9 +87,6 @@ struct edgeport_port { |
3183 | int close_pending; |
3184 | int lsr_event; |
3185 | struct async_icount icount; |
3186 | - wait_queue_head_t delta_msr_wait; /* for handling sleeping while |
3187 | - waiting for msr change to |
3188 | - happen */ |
3189 | struct edgeport_serial *edge_serial; |
3190 | struct usb_serial_port *port; |
3191 | __u8 bUartMode; /* Port type, 0: RS232, etc. */ |
3192 | @@ -1518,7 +1515,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr) |
3193 | icount->dcd++; |
3194 | if (msr & EDGEPORT_MSR_DELTA_RI) |
3195 | icount->rng++; |
3196 | - wake_up_interruptible(&edge_port->delta_msr_wait); |
3197 | + wake_up_interruptible(&edge_port->port->delta_msr_wait); |
3198 | } |
3199 | |
3200 | /* Save the new modem status */ |
3201 | @@ -1821,7 +1818,6 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port) |
3202 | dev = port->serial->dev; |
3203 | |
3204 | memset(&(edge_port->icount), 0x00, sizeof(edge_port->icount)); |
3205 | - init_waitqueue_head(&edge_port->delta_msr_wait); |
3206 | |
3207 | /* turn off loopback */ |
3208 | status = ti_do_config(edge_port, UMPC_SET_CLR_LOOPBACK, 0); |
3209 | @@ -2488,10 +2484,14 @@ static int edge_ioctl(struct tty_struct *tty, |
3210 | dev_dbg(&port->dev, "%s - TIOCMIWAIT\n", __func__); |
3211 | cprev = edge_port->icount; |
3212 | while (1) { |
3213 | - interruptible_sleep_on(&edge_port->delta_msr_wait); |
3214 | + interruptible_sleep_on(&port->delta_msr_wait); |
3215 | /* see if a signal did it */ |
3216 | if (signal_pending(current)) |
3217 | return -ERESTARTSYS; |
3218 | + |
3219 | + if (port->serial->disconnected) |
3220 | + return -EIO; |
3221 | + |
3222 | cnow = edge_port->icount; |
3223 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && |
3224 | cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) |
3225 | diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c |
3226 | index d9c8651..3b9f834 100644 |
3227 | --- a/drivers/usb/serial/mct_u232.c |
3228 | +++ b/drivers/usb/serial/mct_u232.c |
3229 | @@ -114,8 +114,6 @@ struct mct_u232_private { |
3230 | unsigned char last_msr; /* Modem Status Register */ |
3231 | unsigned int rx_flags; /* Throttling flags */ |
3232 | struct async_icount icount; |
3233 | - wait_queue_head_t msr_wait; /* for handling sleeping while waiting |
3234 | - for msr change to happen */ |
3235 | }; |
3236 | |
3237 | #define THROTTLED 0x01 |
3238 | @@ -409,7 +407,6 @@ static int mct_u232_port_probe(struct usb_serial_port *port) |
3239 | return -ENOMEM; |
3240 | |
3241 | spin_lock_init(&priv->lock); |
3242 | - init_waitqueue_head(&priv->msr_wait); |
3243 | |
3244 | usb_set_serial_port_data(port, priv); |
3245 | |
3246 | @@ -606,7 +603,7 @@ static void mct_u232_read_int_callback(struct urb *urb) |
3247 | tty_kref_put(tty); |
3248 | } |
3249 | #endif |
3250 | - wake_up_interruptible(&priv->msr_wait); |
3251 | + wake_up_interruptible(&port->delta_msr_wait); |
3252 | spin_unlock_irqrestore(&priv->lock, flags); |
3253 | exit: |
3254 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
3255 | @@ -815,13 +812,17 @@ static int mct_u232_ioctl(struct tty_struct *tty, |
3256 | cprev = mct_u232_port->icount; |
3257 | spin_unlock_irqrestore(&mct_u232_port->lock, flags); |
3258 | for ( ; ; ) { |
3259 | - prepare_to_wait(&mct_u232_port->msr_wait, |
3260 | + prepare_to_wait(&port->delta_msr_wait, |
3261 | &wait, TASK_INTERRUPTIBLE); |
3262 | schedule(); |
3263 | - finish_wait(&mct_u232_port->msr_wait, &wait); |
3264 | + finish_wait(&port->delta_msr_wait, &wait); |
3265 | /* see if a signal did it */ |
3266 | if (signal_pending(current)) |
3267 | return -ERESTARTSYS; |
3268 | + |
3269 | + if (port->serial->disconnected) |
3270 | + return -EIO; |
3271 | + |
3272 | spin_lock_irqsave(&mct_u232_port->lock, flags); |
3273 | cnow = mct_u232_port->icount; |
3274 | spin_unlock_irqrestore(&mct_u232_port->lock, flags); |
3275 | diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c |
3276 | index 66d9e08..3b909e0 100644 |
3277 | --- a/drivers/usb/serial/mos7840.c |
3278 | +++ b/drivers/usb/serial/mos7840.c |
3279 | @@ -219,7 +219,6 @@ struct moschip_port { |
3280 | char open; |
3281 | char open_ports; |
3282 | wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ |
3283 | - wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ |
3284 | int delta_msr_cond; |
3285 | struct async_icount icount; |
3286 | struct usb_serial_port *port; /* loop back to the owner of this object */ |
3287 | @@ -423,6 +422,9 @@ static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr) |
3288 | icount->rng++; |
3289 | smp_wmb(); |
3290 | } |
3291 | + |
3292 | + mos7840_port->delta_msr_cond = 1; |
3293 | + wake_up_interruptible(&port->port->delta_msr_wait); |
3294 | } |
3295 | } |
3296 | |
3297 | @@ -1131,7 +1133,6 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) |
3298 | |
3299 | /* initialize our wait queues */ |
3300 | init_waitqueue_head(&mos7840_port->wait_chase); |
3301 | - init_waitqueue_head(&mos7840_port->delta_msr_wait); |
3302 | |
3303 | /* initialize our icount structure */ |
3304 | memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount)); |
3305 | @@ -2021,8 +2022,6 @@ static void mos7840_change_port_settings(struct tty_struct *tty, |
3306 | mos7840_port->read_urb_busy = false; |
3307 | } |
3308 | } |
3309 | - wake_up(&mos7840_port->delta_msr_wait); |
3310 | - mos7840_port->delta_msr_cond = 1; |
3311 | dev_dbg(&port->dev, "%s - mos7840_port->shadowLCR is End %x\n", __func__, |
3312 | mos7840_port->shadowLCR); |
3313 | } |
3314 | @@ -2223,13 +2222,18 @@ static int mos7840_ioctl(struct tty_struct *tty, |
3315 | while (1) { |
3316 | /* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */ |
3317 | mos7840_port->delta_msr_cond = 0; |
3318 | - wait_event_interruptible(mos7840_port->delta_msr_wait, |
3319 | - (mos7840_port-> |
3320 | + wait_event_interruptible(port->delta_msr_wait, |
3321 | + (port->serial->disconnected || |
3322 | + mos7840_port-> |
3323 | delta_msr_cond == 1)); |
3324 | |
3325 | /* see if a signal did it */ |
3326 | if (signal_pending(current)) |
3327 | return -ERESTARTSYS; |
3328 | + |
3329 | + if (port->serial->disconnected) |
3330 | + return -EIO; |
3331 | + |
3332 | cnow = mos7840_port->icount; |
3333 | smp_rmb(); |
3334 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && |
3335 | diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c |
3336 | index d217fd6..ae4495a 100644 |
3337 | --- a/drivers/usb/serial/oti6858.c |
3338 | +++ b/drivers/usb/serial/oti6858.c |
3339 | @@ -188,7 +188,6 @@ struct oti6858_private { |
3340 | u8 setup_done; |
3341 | struct delayed_work delayed_setup_work; |
3342 | |
3343 | - wait_queue_head_t intr_wait; |
3344 | struct usb_serial_port *port; /* USB port with which associated */ |
3345 | }; |
3346 | |
3347 | @@ -339,7 +338,6 @@ static int oti6858_port_probe(struct usb_serial_port *port) |
3348 | return -ENOMEM; |
3349 | |
3350 | spin_lock_init(&priv->lock); |
3351 | - init_waitqueue_head(&priv->intr_wait); |
3352 | priv->port = port; |
3353 | INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line); |
3354 | INIT_DELAYED_WORK(&priv->delayed_write_work, send_data); |
3355 | @@ -664,11 +662,15 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) |
3356 | spin_unlock_irqrestore(&priv->lock, flags); |
3357 | |
3358 | while (1) { |
3359 | - wait_event_interruptible(priv->intr_wait, |
3360 | + wait_event_interruptible(port->delta_msr_wait, |
3361 | + port->serial->disconnected || |
3362 | priv->status.pin_state != prev); |
3363 | if (signal_pending(current)) |
3364 | return -ERESTARTSYS; |
3365 | |
3366 | + if (port->serial->disconnected) |
3367 | + return -EIO; |
3368 | + |
3369 | spin_lock_irqsave(&priv->lock, flags); |
3370 | status = priv->status.pin_state & PIN_MASK; |
3371 | spin_unlock_irqrestore(&priv->lock, flags); |
3372 | @@ -763,7 +765,7 @@ static void oti6858_read_int_callback(struct urb *urb) |
3373 | |
3374 | if (!priv->transient) { |
3375 | if (xs->pin_state != priv->status.pin_state) |
3376 | - wake_up_interruptible(&priv->intr_wait); |
3377 | + wake_up_interruptible(&port->delta_msr_wait); |
3378 | memcpy(&priv->status, xs, OTI6858_CTRL_PKT_SIZE); |
3379 | } |
3380 | |
3381 | diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c |
3382 | index 6002419..bb056a1 100644 |
3383 | --- a/drivers/usb/serial/pl2303.c |
3384 | +++ b/drivers/usb/serial/pl2303.c |
3385 | @@ -139,7 +139,6 @@ struct pl2303_serial_private { |
3386 | |
3387 | struct pl2303_private { |
3388 | spinlock_t lock; |
3389 | - wait_queue_head_t delta_msr_wait; |
3390 | u8 line_control; |
3391 | u8 line_status; |
3392 | }; |
3393 | @@ -233,7 +232,6 @@ static int pl2303_port_probe(struct usb_serial_port *port) |
3394 | return -ENOMEM; |
3395 | |
3396 | spin_lock_init(&priv->lock); |
3397 | - init_waitqueue_head(&priv->delta_msr_wait); |
3398 | |
3399 | usb_set_serial_port_data(port, priv); |
3400 | |
3401 | @@ -607,11 +605,14 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) |
3402 | spin_unlock_irqrestore(&priv->lock, flags); |
3403 | |
3404 | while (1) { |
3405 | - interruptible_sleep_on(&priv->delta_msr_wait); |
3406 | + interruptible_sleep_on(&port->delta_msr_wait); |
3407 | /* see if a signal did it */ |
3408 | if (signal_pending(current)) |
3409 | return -ERESTARTSYS; |
3410 | |
3411 | + if (port->serial->disconnected) |
3412 | + return -EIO; |
3413 | + |
3414 | spin_lock_irqsave(&priv->lock, flags); |
3415 | status = priv->line_status; |
3416 | spin_unlock_irqrestore(&priv->lock, flags); |
3417 | @@ -719,7 +720,7 @@ static void pl2303_update_line_status(struct usb_serial_port *port, |
3418 | spin_unlock_irqrestore(&priv->lock, flags); |
3419 | if (priv->line_status & UART_BREAK_ERROR) |
3420 | usb_serial_handle_break(port); |
3421 | - wake_up_interruptible(&priv->delta_msr_wait); |
3422 | + wake_up_interruptible(&port->delta_msr_wait); |
3423 | |
3424 | tty = tty_port_tty_get(&port->port); |
3425 | if (!tty) |
3426 | @@ -784,7 +785,7 @@ static void pl2303_process_read_urb(struct urb *urb) |
3427 | line_status = priv->line_status; |
3428 | priv->line_status &= ~UART_STATE_TRANSIENT_MASK; |
3429 | spin_unlock_irqrestore(&priv->lock, flags); |
3430 | - wake_up_interruptible(&priv->delta_msr_wait); |
3431 | + wake_up_interruptible(&port->delta_msr_wait); |
3432 | |
3433 | if (!urb->actual_length) |
3434 | return; |
3435 | diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c |
3436 | index a8d5110..9f34c99 100644 |
3437 | --- a/drivers/usb/serial/quatech2.c |
3438 | +++ b/drivers/usb/serial/quatech2.c |
3439 | @@ -128,7 +128,6 @@ struct qt2_port_private { |
3440 | u8 shadowLSR; |
3441 | u8 shadowMSR; |
3442 | |
3443 | - wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ |
3444 | struct async_icount icount; |
3445 | |
3446 | struct usb_serial_port *port; |
3447 | @@ -506,8 +505,9 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) |
3448 | spin_unlock_irqrestore(&priv->lock, flags); |
3449 | |
3450 | while (1) { |
3451 | - wait_event_interruptible(priv->delta_msr_wait, |
3452 | - ((priv->icount.rng != prev.rng) || |
3453 | + wait_event_interruptible(port->delta_msr_wait, |
3454 | + (port->serial->disconnected || |
3455 | + (priv->icount.rng != prev.rng) || |
3456 | (priv->icount.dsr != prev.dsr) || |
3457 | (priv->icount.dcd != prev.dcd) || |
3458 | (priv->icount.cts != prev.cts))); |
3459 | @@ -515,6 +515,9 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) |
3460 | if (signal_pending(current)) |
3461 | return -ERESTARTSYS; |
3462 | |
3463 | + if (port->serial->disconnected) |
3464 | + return -EIO; |
3465 | + |
3466 | spin_lock_irqsave(&priv->lock, flags); |
3467 | cur = priv->icount; |
3468 | spin_unlock_irqrestore(&priv->lock, flags); |
3469 | @@ -841,7 +844,6 @@ static int qt2_port_probe(struct usb_serial_port *port) |
3470 | |
3471 | spin_lock_init(&port_priv->lock); |
3472 | spin_lock_init(&port_priv->urb_lock); |
3473 | - init_waitqueue_head(&port_priv->delta_msr_wait); |
3474 | port_priv->port = port; |
3475 | |
3476 | port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL); |
3477 | @@ -984,7 +986,7 @@ static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch) |
3478 | if (newMSR & UART_MSR_TERI) |
3479 | port_priv->icount.rng++; |
3480 | |
3481 | - wake_up_interruptible(&port_priv->delta_msr_wait); |
3482 | + wake_up_interruptible(&port->delta_msr_wait); |
3483 | } |
3484 | } |
3485 | |
3486 | diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c |
3487 | index a42536a..85de44d 100644 |
3488 | --- a/drivers/usb/serial/spcp8x5.c |
3489 | +++ b/drivers/usb/serial/spcp8x5.c |
3490 | @@ -149,7 +149,6 @@ enum spcp8x5_type { |
3491 | struct spcp8x5_private { |
3492 | spinlock_t lock; |
3493 | enum spcp8x5_type type; |
3494 | - wait_queue_head_t delta_msr_wait; |
3495 | u8 line_control; |
3496 | u8 line_status; |
3497 | }; |
3498 | @@ -179,7 +178,6 @@ static int spcp8x5_port_probe(struct usb_serial_port *port) |
3499 | return -ENOMEM; |
3500 | |
3501 | spin_lock_init(&priv->lock); |
3502 | - init_waitqueue_head(&priv->delta_msr_wait); |
3503 | priv->type = type; |
3504 | |
3505 | usb_set_serial_port_data(port , priv); |
3506 | @@ -476,7 +474,7 @@ static void spcp8x5_process_read_urb(struct urb *urb) |
3507 | priv->line_status &= ~UART_STATE_TRANSIENT_MASK; |
3508 | spin_unlock_irqrestore(&priv->lock, flags); |
3509 | /* wake up the wait for termios */ |
3510 | - wake_up_interruptible(&priv->delta_msr_wait); |
3511 | + wake_up_interruptible(&port->delta_msr_wait); |
3512 | |
3513 | if (!urb->actual_length) |
3514 | return; |
3515 | @@ -526,12 +524,15 @@ static int spcp8x5_wait_modem_info(struct usb_serial_port *port, |
3516 | |
3517 | while (1) { |
3518 | /* wake up in bulk read */ |
3519 | - interruptible_sleep_on(&priv->delta_msr_wait); |
3520 | + interruptible_sleep_on(&port->delta_msr_wait); |
3521 | |
3522 | /* see if a signal did it */ |
3523 | if (signal_pending(current)) |
3524 | return -ERESTARTSYS; |
3525 | |
3526 | + if (port->serial->disconnected) |
3527 | + return -EIO; |
3528 | + |
3529 | spin_lock_irqsave(&priv->lock, flags); |
3530 | status = priv->line_status; |
3531 | spin_unlock_irqrestore(&priv->lock, flags); |
3532 | diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c |
3533 | index d938396..44d5949 100644 |
3534 | --- a/drivers/usb/serial/ssu100.c |
3535 | +++ b/drivers/usb/serial/ssu100.c |
3536 | @@ -61,7 +61,6 @@ struct ssu100_port_private { |
3537 | spinlock_t status_lock; |
3538 | u8 shadowLSR; |
3539 | u8 shadowMSR; |
3540 | - wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ |
3541 | struct async_icount icount; |
3542 | }; |
3543 | |
3544 | @@ -355,8 +354,9 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) |
3545 | spin_unlock_irqrestore(&priv->status_lock, flags); |
3546 | |
3547 | while (1) { |
3548 | - wait_event_interruptible(priv->delta_msr_wait, |
3549 | - ((priv->icount.rng != prev.rng) || |
3550 | + wait_event_interruptible(port->delta_msr_wait, |
3551 | + (port->serial->disconnected || |
3552 | + (priv->icount.rng != prev.rng) || |
3553 | (priv->icount.dsr != prev.dsr) || |
3554 | (priv->icount.dcd != prev.dcd) || |
3555 | (priv->icount.cts != prev.cts))); |
3556 | @@ -364,6 +364,9 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) |
3557 | if (signal_pending(current)) |
3558 | return -ERESTARTSYS; |
3559 | |
3560 | + if (port->serial->disconnected) |
3561 | + return -EIO; |
3562 | + |
3563 | spin_lock_irqsave(&priv->status_lock, flags); |
3564 | cur = priv->icount; |
3565 | spin_unlock_irqrestore(&priv->status_lock, flags); |
3566 | @@ -445,7 +448,6 @@ static int ssu100_port_probe(struct usb_serial_port *port) |
3567 | return -ENOMEM; |
3568 | |
3569 | spin_lock_init(&priv->status_lock); |
3570 | - init_waitqueue_head(&priv->delta_msr_wait); |
3571 | |
3572 | usb_set_serial_port_data(port, priv); |
3573 | |
3574 | @@ -537,7 +539,7 @@ static void ssu100_update_msr(struct usb_serial_port *port, u8 msr) |
3575 | priv->icount.dcd++; |
3576 | if (msr & UART_MSR_TERI) |
3577 | priv->icount.rng++; |
3578 | - wake_up_interruptible(&priv->delta_msr_wait); |
3579 | + wake_up_interruptible(&port->delta_msr_wait); |
3580 | } |
3581 | } |
3582 | |
3583 | diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c |
3584 | index f2530d2..4a8b685 100644 |
3585 | --- a/drivers/usb/serial/ti_usb_3410_5052.c |
3586 | +++ b/drivers/usb/serial/ti_usb_3410_5052.c |
3587 | @@ -74,7 +74,6 @@ struct ti_port { |
3588 | int tp_flags; |
3589 | int tp_closing_wait;/* in .01 secs */ |
3590 | struct async_icount tp_icount; |
3591 | - wait_queue_head_t tp_msr_wait; /* wait for msr change */ |
3592 | wait_queue_head_t tp_write_wait; |
3593 | struct ti_device *tp_tdev; |
3594 | struct usb_serial_port *tp_port; |
3595 | @@ -432,7 +431,6 @@ static int ti_port_probe(struct usb_serial_port *port) |
3596 | else |
3597 | tport->tp_uart_base_addr = TI_UART2_BASE_ADDR; |
3598 | tport->tp_closing_wait = closing_wait; |
3599 | - init_waitqueue_head(&tport->tp_msr_wait); |
3600 | init_waitqueue_head(&tport->tp_write_wait); |
3601 | if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, GFP_KERNEL)) { |
3602 | kfree(tport); |
3603 | @@ -784,9 +782,13 @@ static int ti_ioctl(struct tty_struct *tty, |
3604 | dev_dbg(&port->dev, "%s - TIOCMIWAIT\n", __func__); |
3605 | cprev = tport->tp_icount; |
3606 | while (1) { |
3607 | - interruptible_sleep_on(&tport->tp_msr_wait); |
3608 | + interruptible_sleep_on(&port->delta_msr_wait); |
3609 | if (signal_pending(current)) |
3610 | return -ERESTARTSYS; |
3611 | + |
3612 | + if (port->serial->disconnected) |
3613 | + return -EIO; |
3614 | + |
3615 | cnow = tport->tp_icount; |
3616 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && |
3617 | cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) |
3618 | @@ -1400,7 +1402,7 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr) |
3619 | icount->dcd++; |
3620 | if (msr & TI_MSR_DELTA_RI) |
3621 | icount->rng++; |
3622 | - wake_up_interruptible(&tport->tp_msr_wait); |
3623 | + wake_up_interruptible(&tport->tp_port->delta_msr_wait); |
3624 | spin_unlock_irqrestore(&tport->tp_lock, flags); |
3625 | } |
3626 | |
3627 | diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c |
3628 | index 3dc3ad2..dec95e8 100644 |
3629 | --- a/drivers/usb/serial/usb-serial.c |
3630 | +++ b/drivers/usb/serial/usb-serial.c |
3631 | @@ -897,6 +897,7 @@ static int usb_serial_probe(struct usb_interface *interface, |
3632 | port->port.ops = &serial_port_ops; |
3633 | port->serial = serial; |
3634 | spin_lock_init(&port->lock); |
3635 | + init_waitqueue_head(&port->delta_msr_wait); |
3636 | /* Keep this for private driver use for the moment but |
3637 | should probably go away */ |
3638 | INIT_WORK(&port->work, usb_serial_port_work); |
3639 | diff --git a/drivers/xen/events.c b/drivers/xen/events.c |
3640 | index 74d77df..8aa3867 100644 |
3641 | --- a/drivers/xen/events.c |
3642 | +++ b/drivers/xen/events.c |
3643 | @@ -388,11 +388,23 @@ static void unmask_evtchn(int port) |
3644 | |
3645 | if (unlikely((cpu != cpu_from_evtchn(port)))) |
3646 | do_hypercall = 1; |
3647 | - else |
3648 | + else { |
3649 | + /* |
3650 | + * Need to clear the mask before checking pending to |
3651 | + * avoid a race with an event becoming pending. |
3652 | + * |
3653 | + * EVTCHNOP_unmask will only trigger an upcall if the |
3654 | + * mask bit was set, so if a hypercall is needed |
3655 | + * remask the event. |
3656 | + */ |
3657 | + sync_clear_bit(port, &s->evtchn_mask[0]); |
3658 | evtchn_pending = sync_test_bit(port, &s->evtchn_pending[0]); |
3659 | |
3660 | - if (unlikely(evtchn_pending && xen_hvm_domain())) |
3661 | - do_hypercall = 1; |
3662 | + if (unlikely(evtchn_pending && xen_hvm_domain())) { |
3663 | + sync_set_bit(port, &s->evtchn_mask[0]); |
3664 | + do_hypercall = 1; |
3665 | + } |
3666 | + } |
3667 | |
3668 | /* Slow path (hypercall) if this is a non-local port or if this is |
3669 | * an hvm domain and an event is pending (hvm domains don't have |
3670 | @@ -403,8 +415,6 @@ static void unmask_evtchn(int port) |
3671 | } else { |
3672 | struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); |
3673 | |
3674 | - sync_clear_bit(port, &s->evtchn_mask[0]); |
3675 | - |
3676 | /* |
3677 | * The following is basically the equivalent of |
3678 | * 'hw_resend_irq'. Just like a real IO-APIC we 'lose |
3679 | diff --git a/drivers/xen/fallback.c b/drivers/xen/fallback.c |
3680 | index 0ef7c4d..b04fb64 100644 |
3681 | --- a/drivers/xen/fallback.c |
3682 | +++ b/drivers/xen/fallback.c |
3683 | @@ -44,7 +44,7 @@ int xen_event_channel_op_compat(int cmd, void *arg) |
3684 | } |
3685 | EXPORT_SYMBOL_GPL(xen_event_channel_op_compat); |
3686 | |
3687 | -int HYPERVISOR_physdev_op_compat(int cmd, void *arg) |
3688 | +int xen_physdev_op_compat(int cmd, void *arg) |
3689 | { |
3690 | struct physdev_op op; |
3691 | int rc; |
3692 | @@ -78,3 +78,4 @@ int HYPERVISOR_physdev_op_compat(int cmd, void *arg) |
3693 | |
3694 | return rc; |
3695 | } |
3696 | +EXPORT_SYMBOL_GPL(xen_physdev_op_compat); |
3697 | diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c |
3698 | index 9204126..a2278ba 100644 |
3699 | --- a/drivers/xen/xen-pciback/pci_stub.c |
3700 | +++ b/drivers/xen/xen-pciback/pci_stub.c |
3701 | @@ -17,6 +17,7 @@ |
3702 | #include <xen/events.h> |
3703 | #include <asm/xen/pci.h> |
3704 | #include <asm/xen/hypervisor.h> |
3705 | +#include <xen/interface/physdev.h> |
3706 | #include "pciback.h" |
3707 | #include "conf_space.h" |
3708 | #include "conf_space_quirks.h" |
3709 | @@ -85,37 +86,52 @@ static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev) |
3710 | static void pcistub_device_release(struct kref *kref) |
3711 | { |
3712 | struct pcistub_device *psdev; |
3713 | + struct pci_dev *dev; |
3714 | struct xen_pcibk_dev_data *dev_data; |
3715 | |
3716 | psdev = container_of(kref, struct pcistub_device, kref); |
3717 | - dev_data = pci_get_drvdata(psdev->dev); |
3718 | + dev = psdev->dev; |
3719 | + dev_data = pci_get_drvdata(dev); |
3720 | |
3721 | - dev_dbg(&psdev->dev->dev, "pcistub_device_release\n"); |
3722 | + dev_dbg(&dev->dev, "pcistub_device_release\n"); |
3723 | |
3724 | - xen_unregister_device_domain_owner(psdev->dev); |
3725 | + xen_unregister_device_domain_owner(dev); |
3726 | |
3727 | /* Call the reset function which does not take lock as this |
3728 | * is called from "unbind" which takes a device_lock mutex. |
3729 | */ |
3730 | - __pci_reset_function_locked(psdev->dev); |
3731 | - if (pci_load_and_free_saved_state(psdev->dev, |
3732 | - &dev_data->pci_saved_state)) { |
3733 | - dev_dbg(&psdev->dev->dev, "Could not reload PCI state\n"); |
3734 | - } else |
3735 | - pci_restore_state(psdev->dev); |
3736 | + __pci_reset_function_locked(dev); |
3737 | + if (pci_load_and_free_saved_state(dev, &dev_data->pci_saved_state)) |
3738 | + dev_dbg(&dev->dev, "Could not reload PCI state\n"); |
3739 | + else |
3740 | + pci_restore_state(dev); |
3741 | + |
3742 | + if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) { |
3743 | + struct physdev_pci_device ppdev = { |
3744 | + .seg = pci_domain_nr(dev->bus), |
3745 | + .bus = dev->bus->number, |
3746 | + .devfn = dev->devfn |
3747 | + }; |
3748 | + int err = HYPERVISOR_physdev_op(PHYSDEVOP_release_msix, |
3749 | + &ppdev); |
3750 | + |
3751 | + if (err) |
3752 | + dev_warn(&dev->dev, "MSI-X release failed (%d)\n", |
3753 | + err); |
3754 | + } |
3755 | |
3756 | /* Disable the device */ |
3757 | - xen_pcibk_reset_device(psdev->dev); |
3758 | + xen_pcibk_reset_device(dev); |
3759 | |
3760 | kfree(dev_data); |
3761 | - pci_set_drvdata(psdev->dev, NULL); |
3762 | + pci_set_drvdata(dev, NULL); |
3763 | |
3764 | /* Clean-up the device */ |
3765 | - xen_pcibk_config_free_dyn_fields(psdev->dev); |
3766 | - xen_pcibk_config_free_dev(psdev->dev); |
3767 | + xen_pcibk_config_free_dyn_fields(dev); |
3768 | + xen_pcibk_config_free_dev(dev); |
3769 | |
3770 | - psdev->dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED; |
3771 | - pci_dev_put(psdev->dev); |
3772 | + dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED; |
3773 | + pci_dev_put(dev); |
3774 | |
3775 | kfree(psdev); |
3776 | } |
3777 | @@ -355,6 +371,19 @@ static int pcistub_init_device(struct pci_dev *dev) |
3778 | if (err) |
3779 | goto config_release; |
3780 | |
3781 | + if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) { |
3782 | + struct physdev_pci_device ppdev = { |
3783 | + .seg = pci_domain_nr(dev->bus), |
3784 | + .bus = dev->bus->number, |
3785 | + .devfn = dev->devfn |
3786 | + }; |
3787 | + |
3788 | + err = HYPERVISOR_physdev_op(PHYSDEVOP_prepare_msix, &ppdev); |
3789 | + if (err) |
3790 | + dev_err(&dev->dev, "MSI-X preparation failed (%d)\n", |
3791 | + err); |
3792 | + } |
3793 | + |
3794 | /* We need the device active to save the state. */ |
3795 | dev_dbg(&dev->dev, "save state of device\n"); |
3796 | pci_save_state(dev); |
3797 | diff --git a/fs/block_dev.c b/fs/block_dev.c |
3798 | index 78edf76..883dc49 100644 |
3799 | --- a/fs/block_dev.c |
3800 | +++ b/fs/block_dev.c |
3801 | @@ -551,6 +551,7 @@ struct block_device *bdgrab(struct block_device *bdev) |
3802 | ihold(bdev->bd_inode); |
3803 | return bdev; |
3804 | } |
3805 | +EXPORT_SYMBOL(bdgrab); |
3806 | |
3807 | long nr_blockdev_pages(void) |
3808 | { |
3809 | diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c |
3810 | index eea5da7..ce1c169 100644 |
3811 | --- a/fs/btrfs/ctree.c |
3812 | +++ b/fs/btrfs/ctree.c |
3813 | @@ -651,6 +651,8 @@ tree_mod_log_insert_root(struct btrfs_fs_info *fs_info, |
3814 | if (tree_mod_dont_log(fs_info, NULL)) |
3815 | return 0; |
3816 | |
3817 | + __tree_mod_log_free_eb(fs_info, old_root); |
3818 | + |
3819 | ret = tree_mod_alloc(fs_info, flags, &tm); |
3820 | if (ret < 0) |
3821 | goto out; |
3822 | @@ -736,7 +738,7 @@ tree_mod_log_search(struct btrfs_fs_info *fs_info, u64 start, u64 min_seq) |
3823 | static noinline void |
3824 | tree_mod_log_eb_copy(struct btrfs_fs_info *fs_info, struct extent_buffer *dst, |
3825 | struct extent_buffer *src, unsigned long dst_offset, |
3826 | - unsigned long src_offset, int nr_items) |
3827 | + unsigned long src_offset, int nr_items, int log_removal) |
3828 | { |
3829 | int ret; |
3830 | int i; |
3831 | @@ -750,10 +752,12 @@ tree_mod_log_eb_copy(struct btrfs_fs_info *fs_info, struct extent_buffer *dst, |
3832 | } |
3833 | |
3834 | for (i = 0; i < nr_items; i++) { |
3835 | - ret = tree_mod_log_insert_key_locked(fs_info, src, |
3836 | - i + src_offset, |
3837 | - MOD_LOG_KEY_REMOVE); |
3838 | - BUG_ON(ret < 0); |
3839 | + if (log_removal) { |
3840 | + ret = tree_mod_log_insert_key_locked(fs_info, src, |
3841 | + i + src_offset, |
3842 | + MOD_LOG_KEY_REMOVE); |
3843 | + BUG_ON(ret < 0); |
3844 | + } |
3845 | ret = tree_mod_log_insert_key_locked(fs_info, dst, |
3846 | i + dst_offset, |
3847 | MOD_LOG_KEY_ADD); |
3848 | @@ -927,7 +931,6 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, |
3849 | ret = btrfs_dec_ref(trans, root, buf, 1, 1); |
3850 | BUG_ON(ret); /* -ENOMEM */ |
3851 | } |
3852 | - tree_mod_log_free_eb(root->fs_info, buf); |
3853 | clean_tree_block(trans, root, buf); |
3854 | *last_ref = 1; |
3855 | } |
3856 | @@ -1046,6 +1049,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, |
3857 | btrfs_set_node_ptr_generation(parent, parent_slot, |
3858 | trans->transid); |
3859 | btrfs_mark_buffer_dirty(parent); |
3860 | + tree_mod_log_free_eb(root->fs_info, buf); |
3861 | btrfs_free_tree_block(trans, root, buf, parent_start, |
3862 | last_ref); |
3863 | } |
3864 | @@ -1755,7 +1759,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, |
3865 | goto enospc; |
3866 | } |
3867 | |
3868 | - tree_mod_log_free_eb(root->fs_info, root->node); |
3869 | tree_mod_log_set_root_pointer(root, child); |
3870 | rcu_assign_pointer(root->node, child); |
3871 | |
3872 | @@ -3000,7 +3003,7 @@ static int push_node_left(struct btrfs_trans_handle *trans, |
3873 | push_items = min(src_nritems - 8, push_items); |
3874 | |
3875 | tree_mod_log_eb_copy(root->fs_info, dst, src, dst_nritems, 0, |
3876 | - push_items); |
3877 | + push_items, 1); |
3878 | copy_extent_buffer(dst, src, |
3879 | btrfs_node_key_ptr_offset(dst_nritems), |
3880 | btrfs_node_key_ptr_offset(0), |
3881 | @@ -3071,7 +3074,7 @@ static int balance_node_right(struct btrfs_trans_handle *trans, |
3882 | sizeof(struct btrfs_key_ptr)); |
3883 | |
3884 | tree_mod_log_eb_copy(root->fs_info, dst, src, 0, |
3885 | - src_nritems - push_items, push_items); |
3886 | + src_nritems - push_items, push_items, 1); |
3887 | copy_extent_buffer(dst, src, |
3888 | btrfs_node_key_ptr_offset(0), |
3889 | btrfs_node_key_ptr_offset(src_nritems - push_items), |
3890 | @@ -3223,12 +3226,18 @@ static noinline int split_node(struct btrfs_trans_handle *trans, |
3891 | int mid; |
3892 | int ret; |
3893 | u32 c_nritems; |
3894 | + int tree_mod_log_removal = 1; |
3895 | |
3896 | c = path->nodes[level]; |
3897 | WARN_ON(btrfs_header_generation(c) != trans->transid); |
3898 | if (c == root->node) { |
3899 | /* trying to split the root, lets make a new one */ |
3900 | ret = insert_new_root(trans, root, path, level + 1); |
3901 | + /* |
3902 | + * removal of root nodes has been logged by |
3903 | + * tree_mod_log_set_root_pointer due to locking |
3904 | + */ |
3905 | + tree_mod_log_removal = 0; |
3906 | if (ret) |
3907 | return ret; |
3908 | } else { |
3909 | @@ -3266,7 +3275,8 @@ static noinline int split_node(struct btrfs_trans_handle *trans, |
3910 | (unsigned long)btrfs_header_chunk_tree_uuid(split), |
3911 | BTRFS_UUID_SIZE); |
3912 | |
3913 | - tree_mod_log_eb_copy(root->fs_info, split, c, 0, mid, c_nritems - mid); |
3914 | + tree_mod_log_eb_copy(root->fs_info, split, c, 0, mid, c_nritems - mid, |
3915 | + tree_mod_log_removal); |
3916 | copy_extent_buffer(split, c, |
3917 | btrfs_node_key_ptr_offset(0), |
3918 | btrfs_node_key_ptr_offset(mid), |
3919 | diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c |
3920 | index 5a3327b..d170412 100644 |
3921 | --- a/fs/btrfs/extent-tree.c |
3922 | +++ b/fs/btrfs/extent-tree.c |
3923 | @@ -4308,7 +4308,7 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info) |
3924 | spin_lock(&sinfo->lock); |
3925 | spin_lock(&block_rsv->lock); |
3926 | |
3927 | - block_rsv->size = num_bytes; |
3928 | + block_rsv->size = min_t(u64, num_bytes, 512 * 1024 * 1024); |
3929 | |
3930 | num_bytes = sinfo->bytes_used + sinfo->bytes_pinned + |
3931 | sinfo->bytes_reserved + sinfo->bytes_readonly + |
3932 | @@ -4601,14 +4601,49 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) |
3933 | * If the inodes csum_bytes is the same as the original |
3934 | * csum_bytes then we know we haven't raced with any free()ers |
3935 | * so we can just reduce our inodes csum bytes and carry on. |
3936 | - * Otherwise we have to do the normal free thing to account for |
3937 | - * the case that the free side didn't free up its reserve |
3938 | - * because of this outstanding reservation. |
3939 | */ |
3940 | - if (BTRFS_I(inode)->csum_bytes == csum_bytes) |
3941 | + if (BTRFS_I(inode)->csum_bytes == csum_bytes) { |
3942 | calc_csum_metadata_size(inode, num_bytes, 0); |
3943 | - else |
3944 | - to_free = calc_csum_metadata_size(inode, num_bytes, 0); |
3945 | + } else { |
3946 | + u64 orig_csum_bytes = BTRFS_I(inode)->csum_bytes; |
3947 | + u64 bytes; |
3948 | + |
3949 | + /* |
3950 | + * This is tricky, but first we need to figure out how much we |
3951 | + * free'd from any free-ers that occured during this |
3952 | + * reservation, so we reset ->csum_bytes to the csum_bytes |
3953 | + * before we dropped our lock, and then call the free for the |
3954 | + * number of bytes that were freed while we were trying our |
3955 | + * reservation. |
3956 | + */ |
3957 | + bytes = csum_bytes - BTRFS_I(inode)->csum_bytes; |
3958 | + BTRFS_I(inode)->csum_bytes = csum_bytes; |
3959 | + to_free = calc_csum_metadata_size(inode, bytes, 0); |
3960 | + |
3961 | + |
3962 | + /* |
3963 | + * Now we need to see how much we would have freed had we not |
3964 | + * been making this reservation and our ->csum_bytes were not |
3965 | + * artificially inflated. |
3966 | + */ |
3967 | + BTRFS_I(inode)->csum_bytes = csum_bytes - num_bytes; |
3968 | + bytes = csum_bytes - orig_csum_bytes; |
3969 | + bytes = calc_csum_metadata_size(inode, bytes, 0); |
3970 | + |
3971 | + /* |
3972 | + * Now reset ->csum_bytes to what it should be. If bytes is |
3973 | + * more than to_free then we would have free'd more space had we |
3974 | + * not had an artificially high ->csum_bytes, so we need to free |
3975 | + * the remainder. If bytes is the same or less then we don't |
3976 | + * need to do anything, the other free-ers did the correct |
3977 | + * thing. |
3978 | + */ |
3979 | + BTRFS_I(inode)->csum_bytes = orig_csum_bytes - num_bytes; |
3980 | + if (bytes > to_free) |
3981 | + to_free = bytes - to_free; |
3982 | + else |
3983 | + to_free = 0; |
3984 | + } |
3985 | spin_unlock(&BTRFS_I(inode)->lock); |
3986 | if (dropped) |
3987 | to_free += btrfs_calc_trans_metadata_size(root, dropped); |
3988 | diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c |
3989 | index 1b319df..125397e 100644 |
3990 | --- a/fs/btrfs/extent_io.c |
3991 | +++ b/fs/btrfs/extent_io.c |
3992 | @@ -1258,6 +1258,39 @@ int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end) |
3993 | GFP_NOFS); |
3994 | } |
3995 | |
3996 | +int extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end) |
3997 | +{ |
3998 | + unsigned long index = start >> PAGE_CACHE_SHIFT; |
3999 | + unsigned long end_index = end >> PAGE_CACHE_SHIFT; |
4000 | + struct page *page; |
4001 | + |
4002 | + while (index <= end_index) { |
4003 | + page = find_get_page(inode->i_mapping, index); |
4004 | + BUG_ON(!page); /* Pages should be in the extent_io_tree */ |
4005 | + clear_page_dirty_for_io(page); |
4006 | + page_cache_release(page); |
4007 | + index++; |
4008 | + } |
4009 | + return 0; |
4010 | +} |
4011 | + |
4012 | +int extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end) |
4013 | +{ |
4014 | + unsigned long index = start >> PAGE_CACHE_SHIFT; |
4015 | + unsigned long end_index = end >> PAGE_CACHE_SHIFT; |
4016 | + struct page *page; |
4017 | + |
4018 | + while (index <= end_index) { |
4019 | + page = find_get_page(inode->i_mapping, index); |
4020 | + BUG_ON(!page); /* Pages should be in the extent_io_tree */ |
4021 | + account_page_redirty(page); |
4022 | + __set_page_dirty_nobuffers(page); |
4023 | + page_cache_release(page); |
4024 | + index++; |
4025 | + } |
4026 | + return 0; |
4027 | +} |
4028 | + |
4029 | /* |
4030 | * helper function to set both pages and extents in the tree writeback |
4031 | */ |
4032 | diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h |
4033 | index 2eacfab..715b474 100644 |
4034 | --- a/fs/btrfs/extent_io.h |
4035 | +++ b/fs/btrfs/extent_io.h |
4036 | @@ -329,6 +329,8 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long offset, |
4037 | unsigned long *map_len); |
4038 | int extent_range_uptodate(struct extent_io_tree *tree, |
4039 | u64 start, u64 end); |
4040 | +int extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end); |
4041 | +int extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end); |
4042 | int extent_clear_unlock_delalloc(struct inode *inode, |
4043 | struct extent_io_tree *tree, |
4044 | u64 start, u64 end, struct page *locked_page, |
4045 | diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c |
4046 | index 659ea81..7c4e6cc 100644 |
4047 | --- a/fs/btrfs/inode.c |
4048 | +++ b/fs/btrfs/inode.c |
4049 | @@ -352,6 +352,7 @@ static noinline int compress_file_range(struct inode *inode, |
4050 | int i; |
4051 | int will_compress; |
4052 | int compress_type = root->fs_info->compress_type; |
4053 | + int redirty = 0; |
4054 | |
4055 | /* if this is a small write inside eof, kick off a defrag */ |
4056 | if ((end - start + 1) < 16 * 1024 && |
4057 | @@ -414,6 +415,17 @@ again: |
4058 | if (BTRFS_I(inode)->force_compress) |
4059 | compress_type = BTRFS_I(inode)->force_compress; |
4060 | |
4061 | + /* |
4062 | + * we need to call clear_page_dirty_for_io on each |
4063 | + * page in the range. Otherwise applications with the file |
4064 | + * mmap'd can wander in and change the page contents while |
4065 | + * we are compressing them. |
4066 | + * |
4067 | + * If the compression fails for any reason, we set the pages |
4068 | + * dirty again later on. |
4069 | + */ |
4070 | + extent_range_clear_dirty_for_io(inode, start, end); |
4071 | + redirty = 1; |
4072 | ret = btrfs_compress_pages(compress_type, |
4073 | inode->i_mapping, start, |
4074 | total_compressed, pages, |
4075 | @@ -555,6 +567,8 @@ cleanup_and_bail_uncompressed: |
4076 | __set_page_dirty_nobuffers(locked_page); |
4077 | /* unlocked later on in the async handlers */ |
4078 | } |
4079 | + if (redirty) |
4080 | + extent_range_redirty_for_io(inode, start, end); |
4081 | add_async_extent(async_cow, start, end - start + 1, |
4082 | 0, NULL, 0, BTRFS_COMPRESS_NONE); |
4083 | *num_added += 1; |
4084 | diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c |
4085 | index 67783e0..48761b6 100644 |
4086 | --- a/fs/btrfs/scrub.c |
4087 | +++ b/fs/btrfs/scrub.c |
4088 | @@ -541,7 +541,6 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock) |
4089 | eb = path->nodes[0]; |
4090 | ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item); |
4091 | item_size = btrfs_item_size_nr(eb, path->slots[0]); |
4092 | - btrfs_release_path(path); |
4093 | |
4094 | if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) { |
4095 | do { |
4096 | @@ -557,7 +556,9 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock) |
4097 | ret < 0 ? -1 : ref_level, |
4098 | ret < 0 ? -1 : ref_root); |
4099 | } while (ret != 1); |
4100 | + btrfs_release_path(path); |
4101 | } else { |
4102 | + btrfs_release_path(path); |
4103 | swarn.path = path; |
4104 | swarn.dev = dev; |
4105 | iterate_extent_inodes(fs_info, found_key.objectid, |
4106 | diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c |
4107 | index b6818ee..744a69b 100644 |
4108 | --- a/fs/btrfs/tree-log.c |
4109 | +++ b/fs/btrfs/tree-log.c |
4110 | @@ -1384,7 +1384,10 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans, |
4111 | |
4112 | btrfs_release_path(path); |
4113 | if (ret == 0) { |
4114 | - btrfs_inc_nlink(inode); |
4115 | + if (!inode->i_nlink) |
4116 | + set_nlink(inode, 1); |
4117 | + else |
4118 | + btrfs_inc_nlink(inode); |
4119 | ret = btrfs_update_inode(trans, root, inode); |
4120 | } else if (ret == -EEXIST) { |
4121 | ret = 0; |
4122 | diff --git a/fs/dcache.c b/fs/dcache.c |
4123 | index 19153a0..c3bbf85 100644 |
4124 | --- a/fs/dcache.c |
4125 | +++ b/fs/dcache.c |
4126 | @@ -2552,7 +2552,6 @@ static int prepend_path(const struct path *path, |
4127 | bool slash = false; |
4128 | int error = 0; |
4129 | |
4130 | - br_read_lock(&vfsmount_lock); |
4131 | while (dentry != root->dentry || vfsmnt != root->mnt) { |
4132 | struct dentry * parent; |
4133 | |
4134 | @@ -2582,8 +2581,6 @@ static int prepend_path(const struct path *path, |
4135 | if (!error && !slash) |
4136 | error = prepend(buffer, buflen, "/", 1); |
4137 | |
4138 | -out: |
4139 | - br_read_unlock(&vfsmount_lock); |
4140 | return error; |
4141 | |
4142 | global_root: |
4143 | @@ -2600,7 +2597,7 @@ global_root: |
4144 | error = prepend(buffer, buflen, "/", 1); |
4145 | if (!error) |
4146 | error = is_mounted(vfsmnt) ? 1 : 2; |
4147 | - goto out; |
4148 | + return error; |
4149 | } |
4150 | |
4151 | /** |
4152 | @@ -2627,9 +2624,11 @@ char *__d_path(const struct path *path, |
4153 | int error; |
4154 | |
4155 | prepend(&res, &buflen, "\0", 1); |
4156 | + br_read_lock(&vfsmount_lock); |
4157 | write_seqlock(&rename_lock); |
4158 | error = prepend_path(path, root, &res, &buflen); |
4159 | write_sequnlock(&rename_lock); |
4160 | + br_read_unlock(&vfsmount_lock); |
4161 | |
4162 | if (error < 0) |
4163 | return ERR_PTR(error); |
4164 | @@ -2646,9 +2645,11 @@ char *d_absolute_path(const struct path *path, |
4165 | int error; |
4166 | |
4167 | prepend(&res, &buflen, "\0", 1); |
4168 | + br_read_lock(&vfsmount_lock); |
4169 | write_seqlock(&rename_lock); |
4170 | error = prepend_path(path, &root, &res, &buflen); |
4171 | write_sequnlock(&rename_lock); |
4172 | + br_read_unlock(&vfsmount_lock); |
4173 | |
4174 | if (error > 1) |
4175 | error = -EINVAL; |
4176 | @@ -2712,11 +2713,13 @@ char *d_path(const struct path *path, char *buf, int buflen) |
4177 | return path->dentry->d_op->d_dname(path->dentry, buf, buflen); |
4178 | |
4179 | get_fs_root(current->fs, &root); |
4180 | + br_read_lock(&vfsmount_lock); |
4181 | write_seqlock(&rename_lock); |
4182 | error = path_with_deleted(path, &root, &res, &buflen); |
4183 | + write_sequnlock(&rename_lock); |
4184 | + br_read_unlock(&vfsmount_lock); |
4185 | if (error < 0) |
4186 | res = ERR_PTR(error); |
4187 | - write_sequnlock(&rename_lock); |
4188 | path_put(&root); |
4189 | return res; |
4190 | } |
4191 | @@ -2871,6 +2874,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) |
4192 | get_fs_root_and_pwd(current->fs, &root, &pwd); |
4193 | |
4194 | error = -ENOENT; |
4195 | + br_read_lock(&vfsmount_lock); |
4196 | write_seqlock(&rename_lock); |
4197 | if (!d_unlinked(pwd.dentry)) { |
4198 | unsigned long len; |
4199 | @@ -2880,6 +2884,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) |
4200 | prepend(&cwd, &buflen, "\0", 1); |
4201 | error = prepend_path(&pwd, &root, &cwd, &buflen); |
4202 | write_sequnlock(&rename_lock); |
4203 | + br_read_unlock(&vfsmount_lock); |
4204 | |
4205 | if (error < 0) |
4206 | goto out; |
4207 | @@ -2900,6 +2905,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) |
4208 | } |
4209 | } else { |
4210 | write_sequnlock(&rename_lock); |
4211 | + br_read_unlock(&vfsmount_lock); |
4212 | } |
4213 | |
4214 | out: |
4215 | diff --git a/fs/namespace.c b/fs/namespace.c |
4216 | index a51054f..5dd7709 100644 |
4217 | --- a/fs/namespace.c |
4218 | +++ b/fs/namespace.c |
4219 | @@ -798,6 +798,10 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, |
4220 | } |
4221 | |
4222 | mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~MNT_WRITE_HOLD; |
4223 | + /* Don't allow unprivileged users to change mount flags */ |
4224 | + if ((flag & CL_UNPRIVILEGED) && (mnt->mnt.mnt_flags & MNT_READONLY)) |
4225 | + mnt->mnt.mnt_flags |= MNT_LOCK_READONLY; |
4226 | + |
4227 | atomic_inc(&sb->s_active); |
4228 | mnt->mnt.mnt_sb = sb; |
4229 | mnt->mnt.mnt_root = dget(root); |
4230 | @@ -1736,6 +1740,9 @@ static int change_mount_flags(struct vfsmount *mnt, int ms_flags) |
4231 | if (readonly_request == __mnt_is_readonly(mnt)) |
4232 | return 0; |
4233 | |
4234 | + if (mnt->mnt_flags & MNT_LOCK_READONLY) |
4235 | + return -EPERM; |
4236 | + |
4237 | if (readonly_request) |
4238 | error = mnt_make_readonly(real_mount(mnt)); |
4239 | else |
4240 | @@ -2365,7 +2372,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, |
4241 | /* First pass: copy the tree topology */ |
4242 | copy_flags = CL_COPY_ALL | CL_EXPIRE; |
4243 | if (user_ns != mnt_ns->user_ns) |
4244 | - copy_flags |= CL_SHARED_TO_SLAVE; |
4245 | + copy_flags |= CL_SHARED_TO_SLAVE | CL_UNPRIVILEGED; |
4246 | new = copy_tree(old, old->mnt.mnt_root, copy_flags); |
4247 | if (IS_ERR(new)) { |
4248 | up_write(&namespace_sem); |
4249 | @@ -2758,6 +2765,51 @@ bool our_mnt(struct vfsmount *mnt) |
4250 | return check_mnt(real_mount(mnt)); |
4251 | } |
4252 | |
4253 | +bool current_chrooted(void) |
4254 | +{ |
4255 | + /* Does the current process have a non-standard root */ |
4256 | + struct path ns_root; |
4257 | + struct path fs_root; |
4258 | + bool chrooted; |
4259 | + |
4260 | + /* Find the namespace root */ |
4261 | + ns_root.mnt = ¤t->nsproxy->mnt_ns->root->mnt; |
4262 | + ns_root.dentry = ns_root.mnt->mnt_root; |
4263 | + path_get(&ns_root); |
4264 | + while (d_mountpoint(ns_root.dentry) && follow_down_one(&ns_root)) |
4265 | + ; |
4266 | + |
4267 | + get_fs_root(current->fs, &fs_root); |
4268 | + |
4269 | + chrooted = !path_equal(&fs_root, &ns_root); |
4270 | + |
4271 | + path_put(&fs_root); |
4272 | + path_put(&ns_root); |
4273 | + |
4274 | + return chrooted; |
4275 | +} |
4276 | + |
4277 | +void update_mnt_policy(struct user_namespace *userns) |
4278 | +{ |
4279 | + struct mnt_namespace *ns = current->nsproxy->mnt_ns; |
4280 | + struct mount *mnt; |
4281 | + |
4282 | + down_read(&namespace_sem); |
4283 | + list_for_each_entry(mnt, &ns->list, mnt_list) { |
4284 | + switch (mnt->mnt.mnt_sb->s_magic) { |
4285 | + case SYSFS_MAGIC: |
4286 | + userns->may_mount_sysfs = true; |
4287 | + break; |
4288 | + case PROC_SUPER_MAGIC: |
4289 | + userns->may_mount_proc = true; |
4290 | + break; |
4291 | + } |
4292 | + if (userns->may_mount_sysfs && userns->may_mount_proc) |
4293 | + break; |
4294 | + } |
4295 | + up_read(&namespace_sem); |
4296 | +} |
4297 | + |
4298 | static void *mntns_get(struct task_struct *task) |
4299 | { |
4300 | struct mnt_namespace *ns = NULL; |
4301 | diff --git a/fs/nfs/blocklayout/blocklayoutdm.c b/fs/nfs/blocklayout/blocklayoutdm.c |
4302 | index 737d839..6fc7b5c 100644 |
4303 | --- a/fs/nfs/blocklayout/blocklayoutdm.c |
4304 | +++ b/fs/nfs/blocklayout/blocklayoutdm.c |
4305 | @@ -55,7 +55,8 @@ static void dev_remove(struct net *net, dev_t dev) |
4306 | |
4307 | bl_pipe_msg.bl_wq = &nn->bl_wq; |
4308 | memset(msg, 0, sizeof(*msg)); |
4309 | - msg->data = kzalloc(1 + sizeof(bl_umount_request), GFP_NOFS); |
4310 | + msg->len = sizeof(bl_msg) + bl_msg.totallen; |
4311 | + msg->data = kzalloc(msg->len, GFP_NOFS); |
4312 | if (!msg->data) |
4313 | goto out; |
4314 | |
4315 | @@ -66,7 +67,6 @@ static void dev_remove(struct net *net, dev_t dev) |
4316 | memcpy(msg->data, &bl_msg, sizeof(bl_msg)); |
4317 | dataptr = (uint8_t *) msg->data; |
4318 | memcpy(&dataptr[sizeof(bl_msg)], &bl_umount_request, sizeof(bl_umount_request)); |
4319 | - msg->len = sizeof(bl_msg) + bl_msg.totallen; |
4320 | |
4321 | add_wait_queue(&nn->bl_wq, &wq); |
4322 | if (rpc_queue_upcall(nn->bl_device_pipe, msg) < 0) { |
4323 | diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c |
4324 | index bc3968f..cf4ed87 100644 |
4325 | --- a/fs/nfs/idmap.c |
4326 | +++ b/fs/nfs/idmap.c |
4327 | @@ -725,9 +725,9 @@ out1: |
4328 | return ret; |
4329 | } |
4330 | |
4331 | -static int nfs_idmap_instantiate(struct key *key, struct key *authkey, char *data) |
4332 | +static int nfs_idmap_instantiate(struct key *key, struct key *authkey, char *data, size_t datalen) |
4333 | { |
4334 | - return key_instantiate_and_link(key, data, strlen(data) + 1, |
4335 | + return key_instantiate_and_link(key, data, datalen, |
4336 | id_resolver_cache->thread_keyring, |
4337 | authkey); |
4338 | } |
4339 | @@ -737,6 +737,7 @@ static int nfs_idmap_read_and_verify_message(struct idmap_msg *im, |
4340 | struct key *key, struct key *authkey) |
4341 | { |
4342 | char id_str[NFS_UINT_MAXLEN]; |
4343 | + size_t len; |
4344 | int ret = -ENOKEY; |
4345 | |
4346 | /* ret = -ENOKEY */ |
4347 | @@ -746,13 +747,15 @@ static int nfs_idmap_read_and_verify_message(struct idmap_msg *im, |
4348 | case IDMAP_CONV_NAMETOID: |
4349 | if (strcmp(upcall->im_name, im->im_name) != 0) |
4350 | break; |
4351 | - sprintf(id_str, "%d", im->im_id); |
4352 | - ret = nfs_idmap_instantiate(key, authkey, id_str); |
4353 | + /* Note: here we store the NUL terminator too */ |
4354 | + len = sprintf(id_str, "%d", im->im_id) + 1; |
4355 | + ret = nfs_idmap_instantiate(key, authkey, id_str, len); |
4356 | break; |
4357 | case IDMAP_CONV_IDTONAME: |
4358 | if (upcall->im_id != im->im_id) |
4359 | break; |
4360 | - ret = nfs_idmap_instantiate(key, authkey, im->im_name); |
4361 | + len = strlen(im->im_name); |
4362 | + ret = nfs_idmap_instantiate(key, authkey, im->im_name, len); |
4363 | break; |
4364 | default: |
4365 | ret = -EINVAL; |
4366 | diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c |
4367 | index 49eeb04..4fb234d 100644 |
4368 | --- a/fs/nfs/nfs4filelayout.c |
4369 | +++ b/fs/nfs/nfs4filelayout.c |
4370 | @@ -129,7 +129,6 @@ static void filelayout_fenceme(struct inode *inode, struct pnfs_layout_hdr *lo) |
4371 | { |
4372 | if (!test_and_clear_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) |
4373 | return; |
4374 | - clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags); |
4375 | pnfs_return_layout(inode); |
4376 | } |
4377 | |
4378 | diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c |
4379 | index 3cb5e77..3d905e3 100644 |
4380 | --- a/fs/nfs/nfs4proc.c |
4381 | +++ b/fs/nfs/nfs4proc.c |
4382 | @@ -6366,22 +6366,8 @@ nfs4_layoutcommit_done(struct rpc_task *task, void *calldata) |
4383 | static void nfs4_layoutcommit_release(void *calldata) |
4384 | { |
4385 | struct nfs4_layoutcommit_data *data = calldata; |
4386 | - struct pnfs_layout_segment *lseg, *tmp; |
4387 | - unsigned long *bitlock = &NFS_I(data->args.inode)->flags; |
4388 | |
4389 | pnfs_cleanup_layoutcommit(data); |
4390 | - /* Matched by references in pnfs_set_layoutcommit */ |
4391 | - list_for_each_entry_safe(lseg, tmp, &data->lseg_list, pls_lc_list) { |
4392 | - list_del_init(&lseg->pls_lc_list); |
4393 | - if (test_and_clear_bit(NFS_LSEG_LAYOUTCOMMIT, |
4394 | - &lseg->pls_flags)) |
4395 | - pnfs_put_lseg(lseg); |
4396 | - } |
4397 | - |
4398 | - clear_bit_unlock(NFS_INO_LAYOUTCOMMITTING, bitlock); |
4399 | - smp_mb__after_clear_bit(); |
4400 | - wake_up_bit(bitlock, NFS_INO_LAYOUTCOMMITTING); |
4401 | - |
4402 | put_rpccred(data->cred); |
4403 | kfree(data); |
4404 | } |
4405 | diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c |
4406 | index 97767c8..3b71623 100644 |
4407 | --- a/fs/nfs/pnfs.c |
4408 | +++ b/fs/nfs/pnfs.c |
4409 | @@ -417,6 +417,16 @@ should_free_lseg(struct pnfs_layout_range *lseg_range, |
4410 | lo_seg_intersecting(lseg_range, recall_range); |
4411 | } |
4412 | |
4413 | +static bool pnfs_lseg_dec_and_remove_zero(struct pnfs_layout_segment *lseg, |
4414 | + struct list_head *tmp_list) |
4415 | +{ |
4416 | + if (!atomic_dec_and_test(&lseg->pls_refcount)) |
4417 | + return false; |
4418 | + pnfs_layout_remove_lseg(lseg->pls_layout, lseg); |
4419 | + list_add(&lseg->pls_list, tmp_list); |
4420 | + return true; |
4421 | +} |
4422 | + |
4423 | /* Returns 1 if lseg is removed from list, 0 otherwise */ |
4424 | static int mark_lseg_invalid(struct pnfs_layout_segment *lseg, |
4425 | struct list_head *tmp_list) |
4426 | @@ -430,11 +440,8 @@ static int mark_lseg_invalid(struct pnfs_layout_segment *lseg, |
4427 | */ |
4428 | dprintk("%s: lseg %p ref %d\n", __func__, lseg, |
4429 | atomic_read(&lseg->pls_refcount)); |
4430 | - if (atomic_dec_and_test(&lseg->pls_refcount)) { |
4431 | - pnfs_layout_remove_lseg(lseg->pls_layout, lseg); |
4432 | - list_add(&lseg->pls_list, tmp_list); |
4433 | + if (pnfs_lseg_dec_and_remove_zero(lseg, tmp_list)) |
4434 | rv = 1; |
4435 | - } |
4436 | } |
4437 | return rv; |
4438 | } |
4439 | @@ -777,6 +784,21 @@ send_layoutget(struct pnfs_layout_hdr *lo, |
4440 | return lseg; |
4441 | } |
4442 | |
4443 | +static void pnfs_clear_layoutcommit(struct inode *inode, |
4444 | + struct list_head *head) |
4445 | +{ |
4446 | + struct nfs_inode *nfsi = NFS_I(inode); |
4447 | + struct pnfs_layout_segment *lseg, *tmp; |
4448 | + |
4449 | + if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) |
4450 | + return; |
4451 | + list_for_each_entry_safe(lseg, tmp, &nfsi->layout->plh_segs, pls_list) { |
4452 | + if (!test_and_clear_bit(NFS_LSEG_LAYOUTCOMMIT, &lseg->pls_flags)) |
4453 | + continue; |
4454 | + pnfs_lseg_dec_and_remove_zero(lseg, head); |
4455 | + } |
4456 | +} |
4457 | + |
4458 | /* |
4459 | * Initiates a LAYOUTRETURN(FILE), and removes the pnfs_layout_hdr |
4460 | * when the layout segment list is empty. |
4461 | @@ -808,6 +830,7 @@ _pnfs_return_layout(struct inode *ino) |
4462 | /* Reference matched in nfs4_layoutreturn_release */ |
4463 | pnfs_get_layout_hdr(lo); |
4464 | empty = list_empty(&lo->plh_segs); |
4465 | + pnfs_clear_layoutcommit(ino, &tmp_list); |
4466 | pnfs_mark_matching_lsegs_invalid(lo, &tmp_list, NULL); |
4467 | /* Don't send a LAYOUTRETURN if list was initially empty */ |
4468 | if (empty) { |
4469 | @@ -820,8 +843,6 @@ _pnfs_return_layout(struct inode *ino) |
4470 | spin_unlock(&ino->i_lock); |
4471 | pnfs_free_lseg_list(&tmp_list); |
4472 | |
4473 | - WARN_ON(test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)); |
4474 | - |
4475 | lrp = kzalloc(sizeof(*lrp), GFP_KERNEL); |
4476 | if (unlikely(lrp == NULL)) { |
4477 | status = -ENOMEM; |
4478 | @@ -1459,7 +1480,6 @@ static void pnfs_ld_handle_write_error(struct nfs_write_data *data) |
4479 | dprintk("pnfs write error = %d\n", hdr->pnfs_error); |
4480 | if (NFS_SERVER(hdr->inode)->pnfs_curr_ld->flags & |
4481 | PNFS_LAYOUTRET_ON_ERROR) { |
4482 | - clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(hdr->inode)->flags); |
4483 | pnfs_return_layout(hdr->inode); |
4484 | } |
4485 | if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) |
4486 | @@ -1614,7 +1634,6 @@ static void pnfs_ld_handle_read_error(struct nfs_read_data *data) |
4487 | dprintk("pnfs read error = %d\n", hdr->pnfs_error); |
4488 | if (NFS_SERVER(hdr->inode)->pnfs_curr_ld->flags & |
4489 | PNFS_LAYOUTRET_ON_ERROR) { |
4490 | - clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(hdr->inode)->flags); |
4491 | pnfs_return_layout(hdr->inode); |
4492 | } |
4493 | if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) |
4494 | @@ -1747,11 +1766,27 @@ static void pnfs_list_write_lseg(struct inode *inode, struct list_head *listp) |
4495 | |
4496 | list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list) { |
4497 | if (lseg->pls_range.iomode == IOMODE_RW && |
4498 | - test_bit(NFS_LSEG_LAYOUTCOMMIT, &lseg->pls_flags)) |
4499 | + test_and_clear_bit(NFS_LSEG_LAYOUTCOMMIT, &lseg->pls_flags)) |
4500 | list_add(&lseg->pls_lc_list, listp); |
4501 | } |
4502 | } |
4503 | |
4504 | +static void pnfs_list_write_lseg_done(struct inode *inode, struct list_head *listp) |
4505 | +{ |
4506 | + struct pnfs_layout_segment *lseg, *tmp; |
4507 | + unsigned long *bitlock = &NFS_I(inode)->flags; |
4508 | + |
4509 | + /* Matched by references in pnfs_set_layoutcommit */ |
4510 | + list_for_each_entry_safe(lseg, tmp, listp, pls_lc_list) { |
4511 | + list_del_init(&lseg->pls_lc_list); |
4512 | + pnfs_put_lseg(lseg); |
4513 | + } |
4514 | + |
4515 | + clear_bit_unlock(NFS_INO_LAYOUTCOMMITTING, bitlock); |
4516 | + smp_mb__after_clear_bit(); |
4517 | + wake_up_bit(bitlock, NFS_INO_LAYOUTCOMMITTING); |
4518 | +} |
4519 | + |
4520 | void pnfs_set_lo_fail(struct pnfs_layout_segment *lseg) |
4521 | { |
4522 | pnfs_layout_io_set_failed(lseg->pls_layout, lseg->pls_range.iomode); |
4523 | @@ -1796,6 +1831,7 @@ void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data) |
4524 | |
4525 | if (nfss->pnfs_curr_ld->cleanup_layoutcommit) |
4526 | nfss->pnfs_curr_ld->cleanup_layoutcommit(data); |
4527 | + pnfs_list_write_lseg_done(data->args.inode, &data->lseg_list); |
4528 | } |
4529 | |
4530 | /* |
4531 | diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c |
4532 | index 0dc1158..d1dd710 100644 |
4533 | --- a/fs/nfsd/nfs4xdr.c |
4534 | +++ b/fs/nfsd/nfs4xdr.c |
4535 | @@ -264,7 +264,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, |
4536 | iattr->ia_valid |= ATTR_SIZE; |
4537 | } |
4538 | if (bmval[0] & FATTR4_WORD0_ACL) { |
4539 | - int nace; |
4540 | + u32 nace; |
4541 | struct nfs4_ace *ace; |
4542 | |
4543 | READ_BUF(4); len += 4; |
4544 | diff --git a/fs/pnode.c b/fs/pnode.c |
4545 | index 3e000a5..8b29d21 100644 |
4546 | --- a/fs/pnode.c |
4547 | +++ b/fs/pnode.c |
4548 | @@ -9,6 +9,7 @@ |
4549 | #include <linux/mnt_namespace.h> |
4550 | #include <linux/mount.h> |
4551 | #include <linux/fs.h> |
4552 | +#include <linux/nsproxy.h> |
4553 | #include "internal.h" |
4554 | #include "pnode.h" |
4555 | |
4556 | @@ -220,6 +221,7 @@ static struct mount *get_source(struct mount *dest, |
4557 | int propagate_mnt(struct mount *dest_mnt, struct dentry *dest_dentry, |
4558 | struct mount *source_mnt, struct list_head *tree_list) |
4559 | { |
4560 | + struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns; |
4561 | struct mount *m, *child; |
4562 | int ret = 0; |
4563 | struct mount *prev_dest_mnt = dest_mnt; |
4564 | @@ -237,6 +239,10 @@ int propagate_mnt(struct mount *dest_mnt, struct dentry *dest_dentry, |
4565 | |
4566 | source = get_source(m, prev_dest_mnt, prev_src_mnt, &type); |
4567 | |
4568 | + /* Notice when we are propagating across user namespaces */ |
4569 | + if (m->mnt_ns->user_ns != user_ns) |
4570 | + type |= CL_UNPRIVILEGED; |
4571 | + |
4572 | child = copy_tree(source, source->mnt.mnt_root, type); |
4573 | if (IS_ERR(child)) { |
4574 | ret = PTR_ERR(child); |
4575 | diff --git a/fs/pnode.h b/fs/pnode.h |
4576 | index 19b853a3..a0493d5 100644 |
4577 | --- a/fs/pnode.h |
4578 | +++ b/fs/pnode.h |
4579 | @@ -23,6 +23,7 @@ |
4580 | #define CL_MAKE_SHARED 0x08 |
4581 | #define CL_PRIVATE 0x10 |
4582 | #define CL_SHARED_TO_SLAVE 0x20 |
4583 | +#define CL_UNPRIVILEGED 0x40 |
4584 | |
4585 | static inline void set_mnt_shared(struct mount *mnt) |
4586 | { |
4587 | diff --git a/fs/proc/root.c b/fs/proc/root.c |
4588 | index c6e9fac..9c7fab1 100644 |
4589 | --- a/fs/proc/root.c |
4590 | +++ b/fs/proc/root.c |
4591 | @@ -16,6 +16,7 @@ |
4592 | #include <linux/sched.h> |
4593 | #include <linux/module.h> |
4594 | #include <linux/bitops.h> |
4595 | +#include <linux/user_namespace.h> |
4596 | #include <linux/mount.h> |
4597 | #include <linux/pid_namespace.h> |
4598 | #include <linux/parser.h> |
4599 | @@ -108,6 +109,9 @@ static struct dentry *proc_mount(struct file_system_type *fs_type, |
4600 | } else { |
4601 | ns = task_active_pid_ns(current); |
4602 | options = data; |
4603 | + |
4604 | + if (!current_user_ns()->may_mount_proc) |
4605 | + return ERR_PTR(-EPERM); |
4606 | } |
4607 | |
4608 | sb = sget(fs_type, proc_test_super, proc_set_super, flags, ns); |
4609 | diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c |
4610 | index 2fbdff6..1f8c823 100644 |
4611 | --- a/fs/sysfs/dir.c |
4612 | +++ b/fs/sysfs/dir.c |
4613 | @@ -1020,6 +1020,8 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) |
4614 | ino = parent_sd->s_ino; |
4615 | if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) == 0) |
4616 | filp->f_pos++; |
4617 | + else |
4618 | + return 0; |
4619 | } |
4620 | if (filp->f_pos == 1) { |
4621 | if (parent_sd->s_parent) |
4622 | @@ -1028,6 +1030,8 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) |
4623 | ino = parent_sd->s_ino; |
4624 | if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0) |
4625 | filp->f_pos++; |
4626 | + else |
4627 | + return 0; |
4628 | } |
4629 | mutex_lock(&sysfs_mutex); |
4630 | for (pos = sysfs_dir_pos(ns, parent_sd, filp->f_pos, pos); |
4631 | @@ -1058,10 +1062,21 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) |
4632 | return 0; |
4633 | } |
4634 | |
4635 | +static loff_t sysfs_dir_llseek(struct file *file, loff_t offset, int whence) |
4636 | +{ |
4637 | + struct inode *inode = file->f_path.dentry->d_inode; |
4638 | + loff_t ret; |
4639 | + |
4640 | + mutex_lock(&inode->i_mutex); |
4641 | + ret = generic_file_llseek(file, offset, whence); |
4642 | + mutex_unlock(&inode->i_mutex); |
4643 | + |
4644 | + return ret; |
4645 | +} |
4646 | |
4647 | const struct file_operations sysfs_dir_operations = { |
4648 | .read = generic_read_dir, |
4649 | .readdir = sysfs_readdir, |
4650 | .release = sysfs_dir_release, |
4651 | - .llseek = generic_file_llseek, |
4652 | + .llseek = sysfs_dir_llseek, |
4653 | }; |
4654 | diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c |
4655 | index db940a9..fb328d1 100644 |
4656 | --- a/fs/sysfs/mount.c |
4657 | +++ b/fs/sysfs/mount.c |
4658 | @@ -19,6 +19,7 @@ |
4659 | #include <linux/module.h> |
4660 | #include <linux/magic.h> |
4661 | #include <linux/slab.h> |
4662 | +#include <linux/user_namespace.h> |
4663 | |
4664 | #include "sysfs.h" |
4665 | |
4666 | @@ -111,6 +112,9 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type, |
4667 | struct super_block *sb; |
4668 | int error; |
4669 | |
4670 | + if (!(flags & MS_KERNMOUNT) && !current_user_ns()->may_mount_sysfs) |
4671 | + return ERR_PTR(-EPERM); |
4672 | + |
4673 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
4674 | if (!info) |
4675 | return ERR_PTR(-ENOMEM); |
4676 | diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h |
4677 | index d0ae3a8..324f931 100644 |
4678 | --- a/include/linux/fs_struct.h |
4679 | +++ b/include/linux/fs_struct.h |
4680 | @@ -50,4 +50,6 @@ static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root, |
4681 | spin_unlock(&fs->lock); |
4682 | } |
4683 | |
4684 | +extern bool current_chrooted(void); |
4685 | + |
4686 | #endif /* _LINUX_FS_STRUCT_H */ |
4687 | diff --git a/include/linux/mount.h b/include/linux/mount.h |
4688 | index d7029f4..73005f9 100644 |
4689 | --- a/include/linux/mount.h |
4690 | +++ b/include/linux/mount.h |
4691 | @@ -47,6 +47,8 @@ struct mnt_namespace; |
4692 | |
4693 | #define MNT_INTERNAL 0x4000 |
4694 | |
4695 | +#define MNT_LOCK_READONLY 0x400000 |
4696 | + |
4697 | struct vfsmount { |
4698 | struct dentry *mnt_root; /* root of the mounted tree */ |
4699 | struct super_block *mnt_sb; /* pointer to superblock */ |
4700 | diff --git a/include/linux/thermal.h b/include/linux/thermal.h |
4701 | index fe82022..90a8dfa 100644 |
4702 | --- a/include/linux/thermal.h |
4703 | +++ b/include/linux/thermal.h |
4704 | @@ -44,7 +44,7 @@ |
4705 | /* Adding event notification support elements */ |
4706 | #define THERMAL_GENL_FAMILY_NAME "thermal_event" |
4707 | #define THERMAL_GENL_VERSION 0x01 |
4708 | -#define THERMAL_GENL_MCAST_GROUP_NAME "thermal_mc_group" |
4709 | +#define THERMAL_GENL_MCAST_GROUP_NAME "thermal_mc_grp" |
4710 | |
4711 | /* Default Thermal Governor */ |
4712 | #if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE) |
4713 | diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h |
4714 | index ef9be7e..1819b59 100644 |
4715 | --- a/include/linux/usb/serial.h |
4716 | +++ b/include/linux/usb/serial.h |
4717 | @@ -66,6 +66,7 @@ |
4718 | * port. |
4719 | * @flags: usb serial port flags |
4720 | * @write_wait: a wait_queue_head_t used by the port. |
4721 | + * @delta_msr_wait: modem-status-change wait queue |
4722 | * @work: work queue entry for the line discipline waking up. |
4723 | * @throttled: nonzero if the read urb is inactive to throttle the device |
4724 | * @throttle_req: nonzero if the tty wants to throttle us |
4725 | @@ -112,6 +113,7 @@ struct usb_serial_port { |
4726 | |
4727 | unsigned long flags; |
4728 | wait_queue_head_t write_wait; |
4729 | + wait_queue_head_t delta_msr_wait; |
4730 | struct work_struct work; |
4731 | char throttled; |
4732 | char throttle_req; |
4733 | diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h |
4734 | index b9bd2e6..5209cfe 100644 |
4735 | --- a/include/linux/user_namespace.h |
4736 | +++ b/include/linux/user_namespace.h |
4737 | @@ -26,6 +26,8 @@ struct user_namespace { |
4738 | kuid_t owner; |
4739 | kgid_t group; |
4740 | unsigned int proc_inum; |
4741 | + bool may_mount_sysfs; |
4742 | + bool may_mount_proc; |
4743 | }; |
4744 | |
4745 | extern struct user_namespace init_user_ns; |
4746 | @@ -82,4 +84,6 @@ static inline void put_user_ns(struct user_namespace *ns) |
4747 | |
4748 | #endif |
4749 | |
4750 | +void update_mnt_policy(struct user_namespace *userns); |
4751 | + |
4752 | #endif /* _LINUX_USER_H */ |
4753 | diff --git a/include/uapi/asm-generic/signal.h b/include/uapi/asm-generic/signal.h |
4754 | index 6fae30f..8cc2850 100644 |
4755 | --- a/include/uapi/asm-generic/signal.h |
4756 | +++ b/include/uapi/asm-generic/signal.h |
4757 | @@ -93,6 +93,10 @@ typedef unsigned long old_sigset_t; |
4758 | |
4759 | #include <asm-generic/signal-defs.h> |
4760 | |
4761 | +#ifdef SA_RESTORER |
4762 | +#define __ARCH_HAS_SA_RESTORER |
4763 | +#endif |
4764 | + |
4765 | struct sigaction { |
4766 | __sighandler_t sa_handler; |
4767 | unsigned long sa_flags; |
4768 | diff --git a/include/uapi/linux/packet_diag.h b/include/uapi/linux/packet_diag.h |
4769 | index 93f5fa9..afafd70 100644 |
4770 | --- a/include/uapi/linux/packet_diag.h |
4771 | +++ b/include/uapi/linux/packet_diag.h |
4772 | @@ -33,9 +33,11 @@ enum { |
4773 | PACKET_DIAG_TX_RING, |
4774 | PACKET_DIAG_FANOUT, |
4775 | |
4776 | - PACKET_DIAG_MAX, |
4777 | + __PACKET_DIAG_MAX, |
4778 | }; |
4779 | |
4780 | +#define PACKET_DIAG_MAX (__PACKET_DIAG_MAX - 1) |
4781 | + |
4782 | struct packet_diag_info { |
4783 | __u32 pdi_index; |
4784 | __u32 pdi_version; |
4785 | diff --git a/include/uapi/linux/unix_diag.h b/include/uapi/linux/unix_diag.h |
4786 | index b8a2494..b9e2a6a 100644 |
4787 | --- a/include/uapi/linux/unix_diag.h |
4788 | +++ b/include/uapi/linux/unix_diag.h |
4789 | @@ -39,9 +39,11 @@ enum { |
4790 | UNIX_DIAG_MEMINFO, |
4791 | UNIX_DIAG_SHUTDOWN, |
4792 | |
4793 | - UNIX_DIAG_MAX, |
4794 | + __UNIX_DIAG_MAX, |
4795 | }; |
4796 | |
4797 | +#define UNIX_DIAG_MAX (__UNIX_DIAG_MAX - 1) |
4798 | + |
4799 | struct unix_diag_vfs { |
4800 | __u32 udiag_vfs_ino; |
4801 | __u32 udiag_vfs_dev; |
4802 | diff --git a/include/xen/interface/io/blkif.h b/include/xen/interface/io/blkif.h |
4803 | index 01c3d62..ffd4652 100644 |
4804 | --- a/include/xen/interface/io/blkif.h |
4805 | +++ b/include/xen/interface/io/blkif.h |
4806 | @@ -138,11 +138,21 @@ struct blkif_request_discard { |
4807 | uint8_t _pad3; |
4808 | } __attribute__((__packed__)); |
4809 | |
4810 | +struct blkif_request_other { |
4811 | + uint8_t _pad1; |
4812 | + blkif_vdev_t _pad2; /* only for read/write requests */ |
4813 | +#ifdef CONFIG_X86_64 |
4814 | + uint32_t _pad3; /* offsetof(blkif_req..,u.other.id)==8*/ |
4815 | +#endif |
4816 | + uint64_t id; /* private guest value, echoed in resp */ |
4817 | +} __attribute__((__packed__)); |
4818 | + |
4819 | struct blkif_request { |
4820 | uint8_t operation; /* BLKIF_OP_??? */ |
4821 | union { |
4822 | struct blkif_request_rw rw; |
4823 | struct blkif_request_discard discard; |
4824 | + struct blkif_request_other other; |
4825 | } u; |
4826 | } __attribute__((__packed__)); |
4827 | |
4828 | diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h |
4829 | index 1844d31..7000bb1 100644 |
4830 | --- a/include/xen/interface/physdev.h |
4831 | +++ b/include/xen/interface/physdev.h |
4832 | @@ -251,6 +251,12 @@ struct physdev_pci_device_add { |
4833 | |
4834 | #define PHYSDEVOP_pci_device_remove 26 |
4835 | #define PHYSDEVOP_restore_msi_ext 27 |
4836 | +/* |
4837 | + * Dom0 should use these two to announce MMIO resources assigned to |
4838 | + * MSI-X capable devices won't (prepare) or may (release) change. |
4839 | + */ |
4840 | +#define PHYSDEVOP_prepare_msix 30 |
4841 | +#define PHYSDEVOP_release_msix 31 |
4842 | struct physdev_pci_device { |
4843 | /* IN */ |
4844 | uint16_t seg; |
4845 | diff --git a/ipc/mqueue.c b/ipc/mqueue.c |
4846 | index 6ebfbf5..f3f40dc 100644 |
4847 | --- a/ipc/mqueue.c |
4848 | +++ b/ipc/mqueue.c |
4849 | @@ -330,8 +330,16 @@ static struct dentry *mqueue_mount(struct file_system_type *fs_type, |
4850 | int flags, const char *dev_name, |
4851 | void *data) |
4852 | { |
4853 | - if (!(flags & MS_KERNMOUNT)) |
4854 | - data = current->nsproxy->ipc_ns; |
4855 | + if (!(flags & MS_KERNMOUNT)) { |
4856 | + struct ipc_namespace *ns = current->nsproxy->ipc_ns; |
4857 | + /* Don't allow mounting unless the caller has CAP_SYS_ADMIN |
4858 | + * over the ipc namespace. |
4859 | + */ |
4860 | + if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN)) |
4861 | + return ERR_PTR(-EPERM); |
4862 | + |
4863 | + data = ns; |
4864 | + } |
4865 | return mount_ns(fs_type, flags, data, mqueue_fill_super); |
4866 | } |
4867 | |
4868 | diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c |
4869 | index c1c3dc1..bea15bd 100644 |
4870 | --- a/kernel/pid_namespace.c |
4871 | +++ b/kernel/pid_namespace.c |
4872 | @@ -181,6 +181,7 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) |
4873 | int nr; |
4874 | int rc; |
4875 | struct task_struct *task, *me = current; |
4876 | + int init_pids = thread_group_leader(me) ? 1 : 2; |
4877 | |
4878 | /* Don't allow any more processes into the pid namespace */ |
4879 | disable_pid_allocation(pid_ns); |
4880 | @@ -230,7 +231,7 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) |
4881 | */ |
4882 | for (;;) { |
4883 | set_current_state(TASK_UNINTERRUPTIBLE); |
4884 | - if (pid_ns->nr_hashed == 1) |
4885 | + if (pid_ns->nr_hashed == init_pids) |
4886 | break; |
4887 | schedule(); |
4888 | } |
4889 | diff --git a/kernel/signal.c b/kernel/signal.c |
4890 | index 7591ccc..dec9c30 100644 |
4891 | --- a/kernel/signal.c |
4892 | +++ b/kernel/signal.c |
4893 | @@ -485,7 +485,7 @@ flush_signal_handlers(struct task_struct *t, int force_default) |
4894 | if (force_default || ka->sa.sa_handler != SIG_IGN) |
4895 | ka->sa.sa_handler = SIG_DFL; |
4896 | ka->sa.sa_flags = 0; |
4897 | -#ifdef SA_RESTORER |
4898 | +#ifdef __ARCH_HAS_SA_RESTORER |
4899 | ka->sa.sa_restorer = NULL; |
4900 | #endif |
4901 | sigemptyset(&ka->sa.sa_mask); |
4902 | diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c |
4903 | index 2ffbc24..fe1d581 100644 |
4904 | --- a/kernel/trace/trace.c |
4905 | +++ b/kernel/trace/trace.c |
4906 | @@ -2836,11 +2836,25 @@ static int set_tracer_option(struct tracer *trace, char *cmp, int neg) |
4907 | return -EINVAL; |
4908 | } |
4909 | |
4910 | -static void set_tracer_flags(unsigned int mask, int enabled) |
4911 | +/* Some tracers require overwrite to stay enabled */ |
4912 | +int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set) |
4913 | +{ |
4914 | + if (tracer->enabled && (mask & TRACE_ITER_OVERWRITE) && !set) |
4915 | + return -1; |
4916 | + |
4917 | + return 0; |
4918 | +} |
4919 | + |
4920 | +int set_tracer_flag(unsigned int mask, int enabled) |
4921 | { |
4922 | /* do nothing if flag is already set */ |
4923 | if (!!(trace_flags & mask) == !!enabled) |
4924 | - return; |
4925 | + return 0; |
4926 | + |
4927 | + /* Give the tracer a chance to approve the change */ |
4928 | + if (current_trace->flag_changed) |
4929 | + if (current_trace->flag_changed(current_trace, mask, !!enabled)) |
4930 | + return -EINVAL; |
4931 | |
4932 | if (enabled) |
4933 | trace_flags |= mask; |
4934 | @@ -2859,13 +2873,15 @@ static void set_tracer_flags(unsigned int mask, int enabled) |
4935 | |
4936 | if (mask == TRACE_ITER_PRINTK) |
4937 | trace_printk_start_stop_comm(enabled); |
4938 | + |
4939 | + return 0; |
4940 | } |
4941 | |
4942 | static int trace_set_options(char *option) |
4943 | { |
4944 | char *cmp; |
4945 | int neg = 0; |
4946 | - int ret = 0; |
4947 | + int ret = -ENODEV; |
4948 | int i; |
4949 | |
4950 | cmp = strstrip(option); |
4951 | @@ -2879,7 +2895,7 @@ static int trace_set_options(char *option) |
4952 | |
4953 | for (i = 0; trace_options[i]; i++) { |
4954 | if (strcmp(cmp, trace_options[i]) == 0) { |
4955 | - set_tracer_flags(1 << i, !neg); |
4956 | + ret = set_tracer_flag(1 << i, !neg); |
4957 | break; |
4958 | } |
4959 | } |
4960 | @@ -2898,6 +2914,7 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf, |
4961 | size_t cnt, loff_t *ppos) |
4962 | { |
4963 | char buf[64]; |
4964 | + int ret; |
4965 | |
4966 | if (cnt >= sizeof(buf)) |
4967 | return -EINVAL; |
4968 | @@ -2907,7 +2924,9 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf, |
4969 | |
4970 | buf[cnt] = 0; |
4971 | |
4972 | - trace_set_options(buf); |
4973 | + ret = trace_set_options(buf); |
4974 | + if (ret < 0) |
4975 | + return ret; |
4976 | |
4977 | *ppos += cnt; |
4978 | |
4979 | @@ -3213,6 +3232,9 @@ static int tracing_set_tracer(const char *buf) |
4980 | goto out; |
4981 | |
4982 | trace_branch_disable(); |
4983 | + |
4984 | + current_trace->enabled = false; |
4985 | + |
4986 | if (current_trace && current_trace->reset) |
4987 | current_trace->reset(tr); |
4988 | if (current_trace && current_trace->use_max_tr) { |
4989 | @@ -3244,6 +3266,7 @@ static int tracing_set_tracer(const char *buf) |
4990 | } |
4991 | |
4992 | current_trace = t; |
4993 | + current_trace->enabled = true; |
4994 | trace_branch_enable(tr); |
4995 | out: |
4996 | mutex_unlock(&trace_types_lock); |
4997 | @@ -4648,9 +4671,12 @@ trace_options_core_write(struct file *filp, const char __user *ubuf, size_t cnt, |
4998 | return -EINVAL; |
4999 | |
5000 | mutex_lock(&trace_types_lock); |
5001 | - set_tracer_flags(1 << index, val); |
5002 | + ret = set_tracer_flag(1 << index, val); |
5003 | mutex_unlock(&trace_types_lock); |
5004 | |
5005 | + if (ret < 0) |
5006 | + return ret; |
5007 | + |
5008 | *ppos += cnt; |
5009 | |
5010 | return cnt; |
5011 | diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h |
5012 | index c75d798..23f1d2c 100644 |
5013 | --- a/kernel/trace/trace.h |
5014 | +++ b/kernel/trace/trace.h |
5015 | @@ -283,10 +283,14 @@ struct tracer { |
5016 | enum print_line_t (*print_line)(struct trace_iterator *iter); |
5017 | /* If you handled the flag setting, return 0 */ |
5018 | int (*set_flag)(u32 old_flags, u32 bit, int set); |
5019 | + /* Return 0 if OK with change, else return non-zero */ |
5020 | + int (*flag_changed)(struct tracer *tracer, |
5021 | + u32 mask, int set); |
5022 | struct tracer *next; |
5023 | struct tracer_flags *flags; |
5024 | bool print_max; |
5025 | bool use_max_tr; |
5026 | + bool enabled; |
5027 | }; |
5028 | |
5029 | |
5030 | @@ -835,6 +839,8 @@ extern const char *__stop___trace_bprintk_fmt[]; |
5031 | |
5032 | void trace_printk_init_buffers(void); |
5033 | void trace_printk_start_comm(void); |
5034 | +int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set); |
5035 | +int set_tracer_flag(unsigned int mask, int enabled); |
5036 | |
5037 | #undef FTRACE_ENTRY |
5038 | #define FTRACE_ENTRY(call, struct_name, id, tstruct, print, filter) \ |
5039 | diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c |
5040 | index 713a2ca..443b25b 100644 |
5041 | --- a/kernel/trace/trace_irqsoff.c |
5042 | +++ b/kernel/trace/trace_irqsoff.c |
5043 | @@ -32,7 +32,7 @@ enum { |
5044 | |
5045 | static int trace_type __read_mostly; |
5046 | |
5047 | -static int save_lat_flag; |
5048 | +static int save_flags; |
5049 | |
5050 | static void stop_irqsoff_tracer(struct trace_array *tr, int graph); |
5051 | static int start_irqsoff_tracer(struct trace_array *tr, int graph); |
5052 | @@ -558,8 +558,11 @@ static void stop_irqsoff_tracer(struct trace_array *tr, int graph) |
5053 | |
5054 | static void __irqsoff_tracer_init(struct trace_array *tr) |
5055 | { |
5056 | - save_lat_flag = trace_flags & TRACE_ITER_LATENCY_FMT; |
5057 | - trace_flags |= TRACE_ITER_LATENCY_FMT; |
5058 | + save_flags = trace_flags; |
5059 | + |
5060 | + /* non overwrite screws up the latency tracers */ |
5061 | + set_tracer_flag(TRACE_ITER_OVERWRITE, 1); |
5062 | + set_tracer_flag(TRACE_ITER_LATENCY_FMT, 1); |
5063 | |
5064 | tracing_max_latency = 0; |
5065 | irqsoff_trace = tr; |
5066 | @@ -573,10 +576,13 @@ static void __irqsoff_tracer_init(struct trace_array *tr) |
5067 | |
5068 | static void irqsoff_tracer_reset(struct trace_array *tr) |
5069 | { |
5070 | + int lat_flag = save_flags & TRACE_ITER_LATENCY_FMT; |
5071 | + int overwrite_flag = save_flags & TRACE_ITER_OVERWRITE; |
5072 | + |
5073 | stop_irqsoff_tracer(tr, is_graph()); |
5074 | |
5075 | - if (!save_lat_flag) |
5076 | - trace_flags &= ~TRACE_ITER_LATENCY_FMT; |
5077 | + set_tracer_flag(TRACE_ITER_LATENCY_FMT, lat_flag); |
5078 | + set_tracer_flag(TRACE_ITER_OVERWRITE, overwrite_flag); |
5079 | } |
5080 | |
5081 | static void irqsoff_tracer_start(struct trace_array *tr) |
5082 | @@ -609,6 +615,7 @@ static struct tracer irqsoff_tracer __read_mostly = |
5083 | .print_line = irqsoff_print_line, |
5084 | .flags = &tracer_flags, |
5085 | .set_flag = irqsoff_set_flag, |
5086 | + .flag_changed = trace_keep_overwrite, |
5087 | #ifdef CONFIG_FTRACE_SELFTEST |
5088 | .selftest = trace_selftest_startup_irqsoff, |
5089 | #endif |
5090 | @@ -642,6 +649,7 @@ static struct tracer preemptoff_tracer __read_mostly = |
5091 | .print_line = irqsoff_print_line, |
5092 | .flags = &tracer_flags, |
5093 | .set_flag = irqsoff_set_flag, |
5094 | + .flag_changed = trace_keep_overwrite, |
5095 | #ifdef CONFIG_FTRACE_SELFTEST |
5096 | .selftest = trace_selftest_startup_preemptoff, |
5097 | #endif |
5098 | @@ -677,6 +685,7 @@ static struct tracer preemptirqsoff_tracer __read_mostly = |
5099 | .print_line = irqsoff_print_line, |
5100 | .flags = &tracer_flags, |
5101 | .set_flag = irqsoff_set_flag, |
5102 | + .flag_changed = trace_keep_overwrite, |
5103 | #ifdef CONFIG_FTRACE_SELFTEST |
5104 | .selftest = trace_selftest_startup_preemptirqsoff, |
5105 | #endif |
5106 | diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c |
5107 | index 9fe45fc..17bfec6 100644 |
5108 | --- a/kernel/trace/trace_sched_wakeup.c |
5109 | +++ b/kernel/trace/trace_sched_wakeup.c |
5110 | @@ -36,7 +36,7 @@ static void __wakeup_reset(struct trace_array *tr); |
5111 | static int wakeup_graph_entry(struct ftrace_graph_ent *trace); |
5112 | static void wakeup_graph_return(struct ftrace_graph_ret *trace); |
5113 | |
5114 | -static int save_lat_flag; |
5115 | +static int save_flags; |
5116 | |
5117 | #define TRACE_DISPLAY_GRAPH 1 |
5118 | |
5119 | @@ -540,8 +540,11 @@ static void stop_wakeup_tracer(struct trace_array *tr) |
5120 | |
5121 | static int __wakeup_tracer_init(struct trace_array *tr) |
5122 | { |
5123 | - save_lat_flag = trace_flags & TRACE_ITER_LATENCY_FMT; |
5124 | - trace_flags |= TRACE_ITER_LATENCY_FMT; |
5125 | + save_flags = trace_flags; |
5126 | + |
5127 | + /* non overwrite screws up the latency tracers */ |
5128 | + set_tracer_flag(TRACE_ITER_OVERWRITE, 1); |
5129 | + set_tracer_flag(TRACE_ITER_LATENCY_FMT, 1); |
5130 | |
5131 | tracing_max_latency = 0; |
5132 | wakeup_trace = tr; |
5133 | @@ -563,12 +566,15 @@ static int wakeup_rt_tracer_init(struct trace_array *tr) |
5134 | |
5135 | static void wakeup_tracer_reset(struct trace_array *tr) |
5136 | { |
5137 | + int lat_flag = save_flags & TRACE_ITER_LATENCY_FMT; |
5138 | + int overwrite_flag = save_flags & TRACE_ITER_OVERWRITE; |
5139 | + |
5140 | stop_wakeup_tracer(tr); |
5141 | /* make sure we put back any tasks we are tracing */ |
5142 | wakeup_reset(tr); |
5143 | |
5144 | - if (!save_lat_flag) |
5145 | - trace_flags &= ~TRACE_ITER_LATENCY_FMT; |
5146 | + set_tracer_flag(TRACE_ITER_LATENCY_FMT, lat_flag); |
5147 | + set_tracer_flag(TRACE_ITER_OVERWRITE, overwrite_flag); |
5148 | } |
5149 | |
5150 | static void wakeup_tracer_start(struct trace_array *tr) |
5151 | @@ -594,6 +600,7 @@ static struct tracer wakeup_tracer __read_mostly = |
5152 | .print_line = wakeup_print_line, |
5153 | .flags = &tracer_flags, |
5154 | .set_flag = wakeup_set_flag, |
5155 | + .flag_changed = trace_keep_overwrite, |
5156 | #ifdef CONFIG_FTRACE_SELFTEST |
5157 | .selftest = trace_selftest_startup_wakeup, |
5158 | #endif |
5159 | @@ -615,6 +622,7 @@ static struct tracer wakeup_rt_tracer __read_mostly = |
5160 | .print_line = wakeup_print_line, |
5161 | .flags = &tracer_flags, |
5162 | .set_flag = wakeup_set_flag, |
5163 | + .flag_changed = trace_keep_overwrite, |
5164 | #ifdef CONFIG_FTRACE_SELFTEST |
5165 | .selftest = trace_selftest_startup_wakeup, |
5166 | #endif |
5167 | diff --git a/kernel/user.c b/kernel/user.c |
5168 | index 33acb5e..7f6ff2b 100644 |
5169 | --- a/kernel/user.c |
5170 | +++ b/kernel/user.c |
5171 | @@ -53,6 +53,8 @@ struct user_namespace init_user_ns = { |
5172 | .owner = GLOBAL_ROOT_UID, |
5173 | .group = GLOBAL_ROOT_GID, |
5174 | .proc_inum = PROC_USER_INIT_INO, |
5175 | + .may_mount_sysfs = true, |
5176 | + .may_mount_proc = true, |
5177 | }; |
5178 | EXPORT_SYMBOL_GPL(init_user_ns); |
5179 | |
5180 | diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c |
5181 | index dbfe36a7..f45e128 100644 |
5182 | --- a/kernel/user_namespace.c |
5183 | +++ b/kernel/user_namespace.c |
5184 | @@ -61,6 +61,15 @@ int create_user_ns(struct cred *new) |
5185 | kgid_t group = new->egid; |
5186 | int ret; |
5187 | |
5188 | + /* |
5189 | + * Verify that we can not violate the policy of which files |
5190 | + * may be accessed that is specified by the root directory, |
5191 | + * by verifing that the root directory is at the root of the |
5192 | + * mount namespace which allows all files to be accessed. |
5193 | + */ |
5194 | + if (current_chrooted()) |
5195 | + return -EPERM; |
5196 | + |
5197 | /* The creator needs a mapping in the parent user namespace |
5198 | * or else we won't be able to reasonably tell userspace who |
5199 | * created a user_namespace. |
5200 | @@ -87,6 +96,8 @@ int create_user_ns(struct cred *new) |
5201 | |
5202 | set_cred_user_ns(new, ns); |
5203 | |
5204 | + update_mnt_policy(ns); |
5205 | + |
5206 | return 0; |
5207 | } |
5208 | |
5209 | diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c |
5210 | index a292e80..acc74ad 100644 |
5211 | --- a/net/8021q/vlan.c |
5212 | +++ b/net/8021q/vlan.c |
5213 | @@ -86,13 +86,6 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) |
5214 | |
5215 | grp = &vlan_info->grp; |
5216 | |
5217 | - /* Take it out of our own structures, but be sure to interlock with |
5218 | - * HW accelerating devices or SW vlan input packet processing if |
5219 | - * VLAN is not 0 (leave it there for 802.1p). |
5220 | - */ |
5221 | - if (vlan_id) |
5222 | - vlan_vid_del(real_dev, vlan_id); |
5223 | - |
5224 | grp->nr_vlan_devs--; |
5225 | |
5226 | if (vlan->flags & VLAN_FLAG_GVRP) |
5227 | @@ -108,6 +101,13 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) |
5228 | if (grp->nr_vlan_devs == 0) |
5229 | vlan_gvrp_uninit_applicant(real_dev); |
5230 | |
5231 | + /* Take it out of our own structures, but be sure to interlock with |
5232 | + * HW accelerating devices or SW vlan input packet processing if |
5233 | + * VLAN is not 0 (leave it there for 802.1p). |
5234 | + */ |
5235 | + if (vlan_id) |
5236 | + vlan_vid_del(real_dev, vlan_id); |
5237 | + |
5238 | /* Get rid of the vlan's reference to real_dev */ |
5239 | dev_put(real_dev); |
5240 | } |
5241 | diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c |
5242 | index 57f250c..aaf1957 100644 |
5243 | --- a/net/bluetooth/sco.c |
5244 | +++ b/net/bluetooth/sco.c |
5245 | @@ -361,6 +361,7 @@ static void __sco_sock_close(struct sock *sk) |
5246 | sco_chan_del(sk, ECONNRESET); |
5247 | break; |
5248 | |
5249 | + case BT_CONNECT2: |
5250 | case BT_CONNECT: |
5251 | case BT_DISCONN: |
5252 | sco_chan_del(sk, ECONNRESET); |
5253 | diff --git a/net/core/dev.c b/net/core/dev.c |
5254 | index 1339f77..5d9c43d 100644 |
5255 | --- a/net/core/dev.c |
5256 | +++ b/net/core/dev.c |
5257 | @@ -1591,7 +1591,6 @@ void net_enable_timestamp(void) |
5258 | return; |
5259 | } |
5260 | #endif |
5261 | - WARN_ON(in_interrupt()); |
5262 | static_key_slow_inc(&netstamp_needed); |
5263 | } |
5264 | EXPORT_SYMBOL(net_enable_timestamp); |
5265 | @@ -3277,6 +3276,7 @@ int netdev_rx_handler_register(struct net_device *dev, |
5266 | if (dev->rx_handler) |
5267 | return -EBUSY; |
5268 | |
5269 | + /* Note: rx_handler_data must be set before rx_handler */ |
5270 | rcu_assign_pointer(dev->rx_handler_data, rx_handler_data); |
5271 | rcu_assign_pointer(dev->rx_handler, rx_handler); |
5272 | |
5273 | @@ -3297,6 +3297,11 @@ void netdev_rx_handler_unregister(struct net_device *dev) |
5274 | |
5275 | ASSERT_RTNL(); |
5276 | RCU_INIT_POINTER(dev->rx_handler, NULL); |
5277 | + /* a reader seeing a non NULL rx_handler in a rcu_read_lock() |
5278 | + * section has a guarantee to see a non NULL rx_handler_data |
5279 | + * as well. |
5280 | + */ |
5281 | + synchronize_net(); |
5282 | RCU_INIT_POINTER(dev->rx_handler_data, NULL); |
5283 | } |
5284 | EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister); |
5285 | diff --git a/net/core/flow.c b/net/core/flow.c |
5286 | index b0901ee..3bad824 100644 |
5287 | --- a/net/core/flow.c |
5288 | +++ b/net/core/flow.c |
5289 | @@ -329,7 +329,7 @@ static void flow_cache_flush_per_cpu(void *data) |
5290 | struct flow_flush_info *info = data; |
5291 | struct tasklet_struct *tasklet; |
5292 | |
5293 | - tasklet = this_cpu_ptr(&info->cache->percpu->flush_tasklet); |
5294 | + tasklet = &this_cpu_ptr(info->cache->percpu)->flush_tasklet; |
5295 | tasklet->data = (unsigned long)info; |
5296 | tasklet_schedule(tasklet); |
5297 | } |
5298 | diff --git a/net/core/scm.c b/net/core/scm.c |
5299 | index 905dcc6..2dc6cda 100644 |
5300 | --- a/net/core/scm.c |
5301 | +++ b/net/core/scm.c |
5302 | @@ -24,6 +24,7 @@ |
5303 | #include <linux/interrupt.h> |
5304 | #include <linux/netdevice.h> |
5305 | #include <linux/security.h> |
5306 | +#include <linux/pid_namespace.h> |
5307 | #include <linux/pid.h> |
5308 | #include <linux/nsproxy.h> |
5309 | #include <linux/slab.h> |
5310 | @@ -52,7 +53,8 @@ static __inline__ int scm_check_creds(struct ucred *creds) |
5311 | if (!uid_valid(uid) || !gid_valid(gid)) |
5312 | return -EINVAL; |
5313 | |
5314 | - if ((creds->pid == task_tgid_vnr(current) || nsown_capable(CAP_SYS_ADMIN)) && |
5315 | + if ((creds->pid == task_tgid_vnr(current) || |
5316 | + ns_capable(current->nsproxy->pid_ns->user_ns, CAP_SYS_ADMIN)) && |
5317 | ((uid_eq(uid, cred->uid) || uid_eq(uid, cred->euid) || |
5318 | uid_eq(uid, cred->suid)) || nsown_capable(CAP_SETUID)) && |
5319 | ((gid_eq(gid, cred->gid) || gid_eq(gid, cred->egid) || |
5320 | diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c |
5321 | index 66702d3..9841a71 100644 |
5322 | --- a/net/ipv4/tcp_input.c |
5323 | +++ b/net/ipv4/tcp_input.c |
5324 | @@ -2064,11 +2064,8 @@ void tcp_enter_loss(struct sock *sk, int how) |
5325 | if (tcp_is_reno(tp)) |
5326 | tcp_reset_reno_sack(tp); |
5327 | |
5328 | - if (!how) { |
5329 | - /* Push undo marker, if it was plain RTO and nothing |
5330 | - * was retransmitted. */ |
5331 | - tp->undo_marker = tp->snd_una; |
5332 | - } else { |
5333 | + tp->undo_marker = tp->snd_una; |
5334 | + if (how) { |
5335 | tp->sacked_out = 0; |
5336 | tp->fackets_out = 0; |
5337 | } |
5338 | diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c |
5339 | index c36c6c2..17d659e 100644 |
5340 | --- a/net/ipv4/tcp_output.c |
5341 | +++ b/net/ipv4/tcp_output.c |
5342 | @@ -1809,8 +1809,11 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) |
5343 | goto send_now; |
5344 | } |
5345 | |
5346 | - /* Ok, it looks like it is advisable to defer. */ |
5347 | - tp->tso_deferred = 1 | (jiffies << 1); |
5348 | + /* Ok, it looks like it is advisable to defer. |
5349 | + * Do not rearm the timer if already set to not break TCP ACK clocking. |
5350 | + */ |
5351 | + if (!tp->tso_deferred) |
5352 | + tp->tso_deferred = 1 | (jiffies << 1); |
5353 | |
5354 | return true; |
5355 | |
5356 | diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c |
5357 | index 1b5d8cb..a36d17e 100644 |
5358 | --- a/net/ipv6/addrconf.c |
5359 | +++ b/net/ipv6/addrconf.c |
5360 | @@ -4787,26 +4787,20 @@ static void addrconf_sysctl_unregister(struct inet6_dev *idev) |
5361 | |
5362 | static int __net_init addrconf_init_net(struct net *net) |
5363 | { |
5364 | - int err; |
5365 | + int err = -ENOMEM; |
5366 | struct ipv6_devconf *all, *dflt; |
5367 | |
5368 | - err = -ENOMEM; |
5369 | - all = &ipv6_devconf; |
5370 | - dflt = &ipv6_devconf_dflt; |
5371 | + all = kmemdup(&ipv6_devconf, sizeof(ipv6_devconf), GFP_KERNEL); |
5372 | + if (all == NULL) |
5373 | + goto err_alloc_all; |
5374 | |
5375 | - if (!net_eq(net, &init_net)) { |
5376 | - all = kmemdup(all, sizeof(ipv6_devconf), GFP_KERNEL); |
5377 | - if (all == NULL) |
5378 | - goto err_alloc_all; |
5379 | + dflt = kmemdup(&ipv6_devconf_dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL); |
5380 | + if (dflt == NULL) |
5381 | + goto err_alloc_dflt; |
5382 | |
5383 | - dflt = kmemdup(dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL); |
5384 | - if (dflt == NULL) |
5385 | - goto err_alloc_dflt; |
5386 | - } else { |
5387 | - /* these will be inherited by all namespaces */ |
5388 | - dflt->autoconf = ipv6_defaults.autoconf; |
5389 | - dflt->disable_ipv6 = ipv6_defaults.disable_ipv6; |
5390 | - } |
5391 | + /* these will be inherited by all namespaces */ |
5392 | + dflt->autoconf = ipv6_defaults.autoconf; |
5393 | + dflt->disable_ipv6 = ipv6_defaults.disable_ipv6; |
5394 | |
5395 | net->ipv6.devconf_all = all; |
5396 | net->ipv6.devconf_dflt = dflt; |
5397 | diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c |
5398 | index b196852..dee9964 100644 |
5399 | --- a/net/ipv6/ip6_input.c |
5400 | +++ b/net/ipv6/ip6_input.c |
5401 | @@ -118,6 +118,27 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt |
5402 | ipv6_addr_loopback(&hdr->daddr)) |
5403 | goto err; |
5404 | |
5405 | + /* RFC4291 Errata ID: 3480 |
5406 | + * Interface-Local scope spans only a single interface on a |
5407 | + * node and is useful only for loopback transmission of |
5408 | + * multicast. Packets with interface-local scope received |
5409 | + * from another node must be discarded. |
5410 | + */ |
5411 | + if (!(skb->pkt_type == PACKET_LOOPBACK || |
5412 | + dev->flags & IFF_LOOPBACK) && |
5413 | + ipv6_addr_is_multicast(&hdr->daddr) && |
5414 | + IPV6_ADDR_MC_SCOPE(&hdr->daddr) == 1) |
5415 | + goto err; |
5416 | + |
5417 | + /* RFC4291 2.7 |
5418 | + * Nodes must not originate a packet to a multicast address whose scope |
5419 | + * field contains the reserved value 0; if such a packet is received, it |
5420 | + * must be silently dropped. |
5421 | + */ |
5422 | + if (ipv6_addr_is_multicast(&hdr->daddr) && |
5423 | + IPV6_ADDR_MC_SCOPE(&hdr->daddr) == 0) |
5424 | + goto err; |
5425 | + |
5426 | /* |
5427 | * RFC4291 2.7 |
5428 | * Multicast addresses must not be used as source addresses in IPv6 |
5429 | diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c |
5430 | index b833677..4d04105 100644 |
5431 | --- a/net/irda/af_irda.c |
5432 | +++ b/net/irda/af_irda.c |
5433 | @@ -2584,8 +2584,10 @@ bed: |
5434 | NULL, NULL, NULL); |
5435 | |
5436 | /* Check if the we got some results */ |
5437 | - if (!self->cachedaddr) |
5438 | - return -EAGAIN; /* Didn't find any devices */ |
5439 | + if (!self->cachedaddr) { |
5440 | + err = -EAGAIN; /* Didn't find any devices */ |
5441 | + goto out; |
5442 | + } |
5443 | daddr = self->cachedaddr; |
5444 | /* Cleanup */ |
5445 | self->cachedaddr = 0; |
5446 | diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c |
5447 | index 9979bf8..e14e676 100644 |
5448 | --- a/net/mac80211/mlme.c |
5449 | +++ b/net/mac80211/mlme.c |
5450 | @@ -3401,6 +3401,10 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, |
5451 | ret = 0; |
5452 | |
5453 | out: |
5454 | + /* don't print the message below for VHT mismatch if VHT is disabled */ |
5455 | + if (ret & IEEE80211_STA_DISABLE_VHT) |
5456 | + vht_chandef = *chandef; |
5457 | + |
5458 | while (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef, |
5459 | IEEE80211_CHAN_DISABLED)) { |
5460 | if (WARN_ON(chandef->width == NL80211_CHAN_WIDTH_20_NOHT)) { |
5461 | diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c |
5462 | index ca9fde1..c8b32a0 100644 |
5463 | --- a/net/mac80211/sta_info.c |
5464 | +++ b/net/mac80211/sta_info.c |
5465 | @@ -756,6 +756,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta) |
5466 | struct ieee80211_local *local; |
5467 | struct ieee80211_sub_if_data *sdata; |
5468 | int ret, i; |
5469 | + bool have_key = false; |
5470 | |
5471 | might_sleep(); |
5472 | |
5473 | @@ -783,12 +784,19 @@ int __must_check __sta_info_destroy(struct sta_info *sta) |
5474 | list_del_rcu(&sta->list); |
5475 | |
5476 | mutex_lock(&local->key_mtx); |
5477 | - for (i = 0; i < NUM_DEFAULT_KEYS; i++) |
5478 | + for (i = 0; i < NUM_DEFAULT_KEYS; i++) { |
5479 | __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i])); |
5480 | - if (sta->ptk) |
5481 | + have_key = true; |
5482 | + } |
5483 | + if (sta->ptk) { |
5484 | __ieee80211_key_free(key_mtx_dereference(local, sta->ptk)); |
5485 | + have_key = true; |
5486 | + } |
5487 | mutex_unlock(&local->key_mtx); |
5488 | |
5489 | + if (!have_key) |
5490 | + synchronize_net(); |
5491 | + |
5492 | sta->dead = true; |
5493 | |
5494 | local->num_sta--; |
5495 | diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c |
5496 | index f2aabb6..5a55be3 100644 |
5497 | --- a/net/netlink/genetlink.c |
5498 | +++ b/net/netlink/genetlink.c |
5499 | @@ -142,6 +142,7 @@ int genl_register_mc_group(struct genl_family *family, |
5500 | int err = 0; |
5501 | |
5502 | BUG_ON(grp->name[0] == '\0'); |
5503 | + BUG_ON(memchr(grp->name, '\0', GENL_NAMSIZ) == NULL); |
5504 | |
5505 | genl_lock(); |
5506 | |
5507 | diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c |
5508 | index 4e606fc..5578628 100644 |
5509 | --- a/net/sched/sch_fq_codel.c |
5510 | +++ b/net/sched/sch_fq_codel.c |
5511 | @@ -195,7 +195,7 @@ static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch) |
5512 | flow->deficit = q->quantum; |
5513 | flow->dropped = 0; |
5514 | } |
5515 | - if (++sch->q.qlen < sch->limit) |
5516 | + if (++sch->q.qlen <= sch->limit) |
5517 | return NET_XMIT_SUCCESS; |
5518 | |
5519 | q->drop_overlimit++; |
5520 | diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c |
5521 | index fb20f25..f8529fc 100644 |
5522 | --- a/net/sunrpc/sched.c |
5523 | +++ b/net/sunrpc/sched.c |
5524 | @@ -180,6 +180,8 @@ static void __rpc_add_wait_queue(struct rpc_wait_queue *queue, |
5525 | list_add_tail(&task->u.tk_wait.list, &queue->tasks[0]); |
5526 | task->tk_waitqueue = queue; |
5527 | queue->qlen++; |
5528 | + /* barrier matches the read in rpc_wake_up_task_queue_locked() */ |
5529 | + smp_wmb(); |
5530 | rpc_set_queued(task); |
5531 | |
5532 | dprintk("RPC: %5u added to queue %p \"%s\"\n", |
5533 | @@ -430,8 +432,11 @@ static void __rpc_do_wake_up_task(struct rpc_wait_queue *queue, struct rpc_task |
5534 | */ |
5535 | static void rpc_wake_up_task_queue_locked(struct rpc_wait_queue *queue, struct rpc_task *task) |
5536 | { |
5537 | - if (RPC_IS_QUEUED(task) && task->tk_waitqueue == queue) |
5538 | - __rpc_do_wake_up_task(queue, task); |
5539 | + if (RPC_IS_QUEUED(task)) { |
5540 | + smp_rmb(); |
5541 | + if (task->tk_waitqueue == queue) |
5542 | + __rpc_do_wake_up_task(queue, task); |
5543 | + } |
5544 | } |
5545 | |
5546 | /* |
5547 | diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c |
5548 | index 5b5c876..b45eb65 100644 |
5549 | --- a/net/unix/af_unix.c |
5550 | +++ b/net/unix/af_unix.c |
5551 | @@ -384,7 +384,7 @@ static void unix_sock_destructor(struct sock *sk) |
5552 | #endif |
5553 | } |
5554 | |
5555 | -static int unix_release_sock(struct sock *sk, int embrion) |
5556 | +static void unix_release_sock(struct sock *sk, int embrion) |
5557 | { |
5558 | struct unix_sock *u = unix_sk(sk); |
5559 | struct path path; |
5560 | @@ -453,8 +453,6 @@ static int unix_release_sock(struct sock *sk, int embrion) |
5561 | |
5562 | if (unix_tot_inflight) |
5563 | unix_gc(); /* Garbage collect fds */ |
5564 | - |
5565 | - return 0; |
5566 | } |
5567 | |
5568 | static void init_peercred(struct sock *sk) |
5569 | @@ -701,9 +699,10 @@ static int unix_release(struct socket *sock) |
5570 | if (!sk) |
5571 | return 0; |
5572 | |
5573 | + unix_release_sock(sk, 0); |
5574 | sock->sk = NULL; |
5575 | |
5576 | - return unix_release_sock(sk, 0); |
5577 | + return 0; |
5578 | } |
5579 | |
5580 | static int unix_autobind(struct socket *sock) |