Annotation of /trunk/kernel-alx/patches-3.10/0107-3.10.8-all-fixes.patch
Parent Directory | Revision Log
Revision 2288 -
(hide annotations)
(download)
Wed Sep 25 06:47:47 2013 UTC (11 years ago) by niro
File size: 57613 byte(s)
Wed Sep 25 06:47:47 2013 UTC (11 years ago) by niro
File size: 57613 byte(s)
-linux-3.10 patches
1 | niro | 2288 | diff --git a/Makefile b/Makefile |
2 | index 33e36ab..1a21612 100644 | ||
3 | --- a/Makefile | ||
4 | +++ b/Makefile | ||
5 | @@ -1,6 +1,6 @@ | ||
6 | VERSION = 3 | ||
7 | PATCHLEVEL = 10 | ||
8 | -SUBLEVEL = 7 | ||
9 | +SUBLEVEL = 8 | ||
10 | EXTRAVERSION = | ||
11 | NAME = TOSSUG Baby Fish | ||
12 | |||
13 | diff --git a/arch/Kconfig b/arch/Kconfig | ||
14 | index a4429bc..00e3702 100644 | ||
15 | --- a/arch/Kconfig | ||
16 | +++ b/arch/Kconfig | ||
17 | @@ -404,6 +404,12 @@ config CLONE_BACKWARDS2 | ||
18 | help | ||
19 | Architecture has the first two arguments of clone(2) swapped. | ||
20 | |||
21 | +config CLONE_BACKWARDS3 | ||
22 | + bool | ||
23 | + help | ||
24 | + Architecture has tls passed as the 3rd argument of clone(2), | ||
25 | + not the 5th one. | ||
26 | + | ||
27 | config ODD_RT_SIGACTION | ||
28 | bool | ||
29 | help | ||
30 | diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h | ||
31 | index 18d5032..4bb08e3 100644 | ||
32 | --- a/arch/arm/include/asm/kvm_asm.h | ||
33 | +++ b/arch/arm/include/asm/kvm_asm.h | ||
34 | @@ -37,16 +37,18 @@ | ||
35 | #define c5_AIFSR 15 /* Auxilary Instrunction Fault Status R */ | ||
36 | #define c6_DFAR 16 /* Data Fault Address Register */ | ||
37 | #define c6_IFAR 17 /* Instruction Fault Address Register */ | ||
38 | -#define c9_L2CTLR 18 /* Cortex A15 L2 Control Register */ | ||
39 | -#define c10_PRRR 19 /* Primary Region Remap Register */ | ||
40 | -#define c10_NMRR 20 /* Normal Memory Remap Register */ | ||
41 | -#define c12_VBAR 21 /* Vector Base Address Register */ | ||
42 | -#define c13_CID 22 /* Context ID Register */ | ||
43 | -#define c13_TID_URW 23 /* Thread ID, User R/W */ | ||
44 | -#define c13_TID_URO 24 /* Thread ID, User R/O */ | ||
45 | -#define c13_TID_PRIV 25 /* Thread ID, Privileged */ | ||
46 | -#define c14_CNTKCTL 26 /* Timer Control Register (PL1) */ | ||
47 | -#define NR_CP15_REGS 27 /* Number of regs (incl. invalid) */ | ||
48 | +#define c7_PAR 18 /* Physical Address Register */ | ||
49 | +#define c7_PAR_high 19 /* PAR top 32 bits */ | ||
50 | +#define c9_L2CTLR 20 /* Cortex A15 L2 Control Register */ | ||
51 | +#define c10_PRRR 21 /* Primary Region Remap Register */ | ||
52 | +#define c10_NMRR 22 /* Normal Memory Remap Register */ | ||
53 | +#define c12_VBAR 23 /* Vector Base Address Register */ | ||
54 | +#define c13_CID 24 /* Context ID Register */ | ||
55 | +#define c13_TID_URW 25 /* Thread ID, User R/W */ | ||
56 | +#define c13_TID_URO 26 /* Thread ID, User R/O */ | ||
57 | +#define c13_TID_PRIV 27 /* Thread ID, Privileged */ | ||
58 | +#define c14_CNTKCTL 28 /* Timer Control Register (PL1) */ | ||
59 | +#define NR_CP15_REGS 29 /* Number of regs (incl. invalid) */ | ||
60 | |||
61 | #define ARM_EXCEPTION_RESET 0 | ||
62 | #define ARM_EXCEPTION_UNDEFINED 1 | ||
63 | diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h | ||
64 | index bdf2b84..aa9b4ac 100644 | ||
65 | --- a/arch/arm/include/asm/tlb.h | ||
66 | +++ b/arch/arm/include/asm/tlb.h | ||
67 | @@ -43,6 +43,7 @@ struct mmu_gather { | ||
68 | struct mm_struct *mm; | ||
69 | unsigned int fullmm; | ||
70 | struct vm_area_struct *vma; | ||
71 | + unsigned long start, end; | ||
72 | unsigned long range_start; | ||
73 | unsigned long range_end; | ||
74 | unsigned int nr; | ||
75 | @@ -107,10 +108,12 @@ static inline void tlb_flush_mmu(struct mmu_gather *tlb) | ||
76 | } | ||
77 | |||
78 | static inline void | ||
79 | -tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int fullmm) | ||
80 | +tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) | ||
81 | { | ||
82 | tlb->mm = mm; | ||
83 | - tlb->fullmm = fullmm; | ||
84 | + tlb->fullmm = !(start | (end+1)); | ||
85 | + tlb->start = start; | ||
86 | + tlb->end = end; | ||
87 | tlb->vma = NULL; | ||
88 | tlb->max = ARRAY_SIZE(tlb->local); | ||
89 | tlb->pages = tlb->local; | ||
90 | diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c | ||
91 | index d9f5cd4..e19edc6 100644 | ||
92 | --- a/arch/arm/kernel/perf_event.c | ||
93 | +++ b/arch/arm/kernel/perf_event.c | ||
94 | @@ -53,7 +53,12 @@ armpmu_map_cache_event(const unsigned (*cache_map) | ||
95 | static int | ||
96 | armpmu_map_hw_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config) | ||
97 | { | ||
98 | - int mapping = (*event_map)[config]; | ||
99 | + int mapping; | ||
100 | + | ||
101 | + if (config >= PERF_COUNT_HW_MAX) | ||
102 | + return -ENOENT; | ||
103 | + | ||
104 | + mapping = (*event_map)[config]; | ||
105 | return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping; | ||
106 | } | ||
107 | |||
108 | @@ -253,6 +258,9 @@ validate_event(struct pmu_hw_events *hw_events, | ||
109 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); | ||
110 | struct pmu *leader_pmu = event->group_leader->pmu; | ||
111 | |||
112 | + if (is_software_event(event)) | ||
113 | + return 1; | ||
114 | + | ||
115 | if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) | ||
116 | return 1; | ||
117 | |||
118 | diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c | ||
119 | index 8eea97b..4a51990 100644 | ||
120 | --- a/arch/arm/kvm/coproc.c | ||
121 | +++ b/arch/arm/kvm/coproc.c | ||
122 | @@ -180,6 +180,10 @@ static const struct coproc_reg cp15_regs[] = { | ||
123 | NULL, reset_unknown, c6_DFAR }, | ||
124 | { CRn( 6), CRm( 0), Op1( 0), Op2( 2), is32, | ||
125 | NULL, reset_unknown, c6_IFAR }, | ||
126 | + | ||
127 | + /* PAR swapped by interrupt.S */ | ||
128 | + { CRn( 7), Op1( 0), is64, NULL, reset_unknown64, c7_PAR }, | ||
129 | + | ||
130 | /* | ||
131 | * DC{C,I,CI}SW operations: | ||
132 | */ | ||
133 | diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S | ||
134 | index f7793df..16cd4ba 100644 | ||
135 | --- a/arch/arm/kvm/interrupts.S | ||
136 | +++ b/arch/arm/kvm/interrupts.S | ||
137 | @@ -49,6 +49,7 @@ __kvm_hyp_code_start: | ||
138 | ENTRY(__kvm_tlb_flush_vmid_ipa) | ||
139 | push {r2, r3} | ||
140 | |||
141 | + dsb ishst | ||
142 | add r0, r0, #KVM_VTTBR | ||
143 | ldrd r2, r3, [r0] | ||
144 | mcrr p15, 6, r2, r3, c2 @ Write VTTBR | ||
145 | @@ -291,6 +292,7 @@ THUMB( orr r2, r2, #PSR_T_BIT ) | ||
146 | ldr r2, =BSYM(panic) | ||
147 | msr ELR_hyp, r2 | ||
148 | ldr r0, =\panic_str | ||
149 | + clrex @ Clear exclusive monitor | ||
150 | eret | ||
151 | .endm | ||
152 | |||
153 | @@ -414,6 +416,10 @@ guest_trap: | ||
154 | mrcne p15, 4, r2, c6, c0, 4 @ HPFAR | ||
155 | bne 3f | ||
156 | |||
157 | + /* Preserve PAR */ | ||
158 | + mrrc p15, 0, r0, r1, c7 @ PAR | ||
159 | + push {r0, r1} | ||
160 | + | ||
161 | /* Resolve IPA using the xFAR */ | ||
162 | mcr p15, 0, r2, c7, c8, 0 @ ATS1CPR | ||
163 | isb | ||
164 | @@ -424,13 +430,20 @@ guest_trap: | ||
165 | lsl r2, r2, #4 | ||
166 | orr r2, r2, r1, lsl #24 | ||
167 | |||
168 | + /* Restore PAR */ | ||
169 | + pop {r0, r1} | ||
170 | + mcrr p15, 0, r0, r1, c7 @ PAR | ||
171 | + | ||
172 | 3: load_vcpu @ Load VCPU pointer to r0 | ||
173 | str r2, [r0, #VCPU_HPFAR] | ||
174 | |||
175 | 1: mov r1, #ARM_EXCEPTION_HVC | ||
176 | b __kvm_vcpu_return | ||
177 | |||
178 | -4: pop {r0, r1, r2} @ Failed translation, return to guest | ||
179 | +4: pop {r0, r1} @ Failed translation, return to guest | ||
180 | + mcrr p15, 0, r0, r1, c7 @ PAR | ||
181 | + clrex | ||
182 | + pop {r0, r1, r2} | ||
183 | eret | ||
184 | |||
185 | /* | ||
186 | @@ -456,6 +469,7 @@ switch_to_guest_vfp: | ||
187 | |||
188 | pop {r3-r7} | ||
189 | pop {r0-r2} | ||
190 | + clrex | ||
191 | eret | ||
192 | #endif | ||
193 | |||
194 | diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S | ||
195 | index 3c8f2f0..2b44b95 100644 | ||
196 | --- a/arch/arm/kvm/interrupts_head.S | ||
197 | +++ b/arch/arm/kvm/interrupts_head.S | ||
198 | @@ -302,11 +302,14 @@ vcpu .req r0 @ vcpu pointer always in r0 | ||
199 | .endif | ||
200 | |||
201 | mrc p15, 0, r2, c14, c1, 0 @ CNTKCTL | ||
202 | + mrrc p15, 0, r4, r5, c7 @ PAR | ||
203 | |||
204 | .if \store_to_vcpu == 0 | ||
205 | - push {r2} | ||
206 | + push {r2,r4-r5} | ||
207 | .else | ||
208 | str r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)] | ||
209 | + add r12, vcpu, #CP15_OFFSET(c7_PAR) | ||
210 | + strd r4, r5, [r12] | ||
211 | .endif | ||
212 | .endm | ||
213 | |||
214 | @@ -319,12 +322,15 @@ vcpu .req r0 @ vcpu pointer always in r0 | ||
215 | */ | ||
216 | .macro write_cp15_state read_from_vcpu | ||
217 | .if \read_from_vcpu == 0 | ||
218 | - pop {r2} | ||
219 | + pop {r2,r4-r5} | ||
220 | .else | ||
221 | ldr r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)] | ||
222 | + add r12, vcpu, #CP15_OFFSET(c7_PAR) | ||
223 | + ldrd r4, r5, [r12] | ||
224 | .endif | ||
225 | |||
226 | mcr p15, 0, r2, c14, c1, 0 @ CNTKCTL | ||
227 | + mcrr p15, 0, r4, r5, c7 @ PAR | ||
228 | |||
229 | .if \read_from_vcpu == 0 | ||
230 | pop {r2-r12} | ||
231 | diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h | ||
232 | index 654f096..5546653 100644 | ||
233 | --- a/arch/arm64/include/asm/tlb.h | ||
234 | +++ b/arch/arm64/include/asm/tlb.h | ||
235 | @@ -35,6 +35,7 @@ struct mmu_gather { | ||
236 | struct mm_struct *mm; | ||
237 | unsigned int fullmm; | ||
238 | struct vm_area_struct *vma; | ||
239 | + unsigned long start, end; | ||
240 | unsigned long range_start; | ||
241 | unsigned long range_end; | ||
242 | unsigned int nr; | ||
243 | @@ -97,10 +98,12 @@ static inline void tlb_flush_mmu(struct mmu_gather *tlb) | ||
244 | } | ||
245 | |||
246 | static inline void | ||
247 | -tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int fullmm) | ||
248 | +tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) | ||
249 | { | ||
250 | tlb->mm = mm; | ||
251 | - tlb->fullmm = fullmm; | ||
252 | + tlb->fullmm = !(start | (end+1)); | ||
253 | + tlb->start = start; | ||
254 | + tlb->end = end; | ||
255 | tlb->vma = NULL; | ||
256 | tlb->max = ARRAY_SIZE(tlb->local); | ||
257 | tlb->pages = tlb->local; | ||
258 | diff --git a/arch/ia64/include/asm/tlb.h b/arch/ia64/include/asm/tlb.h | ||
259 | index ef3a9de..bc5efc7 100644 | ||
260 | --- a/arch/ia64/include/asm/tlb.h | ||
261 | +++ b/arch/ia64/include/asm/tlb.h | ||
262 | @@ -22,7 +22,7 @@ | ||
263 | * unmapping a portion of the virtual address space, these hooks are called according to | ||
264 | * the following template: | ||
265 | * | ||
266 | - * tlb <- tlb_gather_mmu(mm, full_mm_flush); // start unmap for address space MM | ||
267 | + * tlb <- tlb_gather_mmu(mm, start, end); // start unmap for address space MM | ||
268 | * { | ||
269 | * for each vma that needs a shootdown do { | ||
270 | * tlb_start_vma(tlb, vma); | ||
271 | @@ -58,6 +58,7 @@ struct mmu_gather { | ||
272 | unsigned int max; | ||
273 | unsigned char fullmm; /* non-zero means full mm flush */ | ||
274 | unsigned char need_flush; /* really unmapped some PTEs? */ | ||
275 | + unsigned long start, end; | ||
276 | unsigned long start_addr; | ||
277 | unsigned long end_addr; | ||
278 | struct page **pages; | ||
279 | @@ -155,13 +156,15 @@ static inline void __tlb_alloc_page(struct mmu_gather *tlb) | ||
280 | |||
281 | |||
282 | static inline void | ||
283 | -tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush) | ||
284 | +tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) | ||
285 | { | ||
286 | tlb->mm = mm; | ||
287 | tlb->max = ARRAY_SIZE(tlb->local); | ||
288 | tlb->pages = tlb->local; | ||
289 | tlb->nr = 0; | ||
290 | - tlb->fullmm = full_mm_flush; | ||
291 | + tlb->fullmm = !(start | (end+1)); | ||
292 | + tlb->start = start; | ||
293 | + tlb->end = end; | ||
294 | tlb->start_addr = ~0UL; | ||
295 | } | ||
296 | |||
297 | diff --git a/arch/m68k/emu/natfeat.c b/arch/m68k/emu/natfeat.c | ||
298 | index 2291a7d..fa277ae 100644 | ||
299 | --- a/arch/m68k/emu/natfeat.c | ||
300 | +++ b/arch/m68k/emu/natfeat.c | ||
301 | @@ -18,9 +18,11 @@ | ||
302 | #include <asm/machdep.h> | ||
303 | #include <asm/natfeat.h> | ||
304 | |||
305 | +extern long nf_get_id2(const char *feature_name); | ||
306 | + | ||
307 | asm("\n" | ||
308 | -" .global nf_get_id,nf_call\n" | ||
309 | -"nf_get_id:\n" | ||
310 | +" .global nf_get_id2,nf_call\n" | ||
311 | +"nf_get_id2:\n" | ||
312 | " .short 0x7300\n" | ||
313 | " rts\n" | ||
314 | "nf_call:\n" | ||
315 | @@ -29,12 +31,25 @@ asm("\n" | ||
316 | "1: moveq.l #0,%d0\n" | ||
317 | " rts\n" | ||
318 | " .section __ex_table,\"a\"\n" | ||
319 | -" .long nf_get_id,1b\n" | ||
320 | +" .long nf_get_id2,1b\n" | ||
321 | " .long nf_call,1b\n" | ||
322 | " .previous"); | ||
323 | -EXPORT_SYMBOL_GPL(nf_get_id); | ||
324 | EXPORT_SYMBOL_GPL(nf_call); | ||
325 | |||
326 | +long nf_get_id(const char *feature_name) | ||
327 | +{ | ||
328 | + /* feature_name may be in vmalloc()ed memory, so make a copy */ | ||
329 | + char name_copy[32]; | ||
330 | + size_t n; | ||
331 | + | ||
332 | + n = strlcpy(name_copy, feature_name, sizeof(name_copy)); | ||
333 | + if (n >= sizeof(name_copy)) | ||
334 | + return 0; | ||
335 | + | ||
336 | + return nf_get_id2(name_copy); | ||
337 | +} | ||
338 | +EXPORT_SYMBOL_GPL(nf_get_id); | ||
339 | + | ||
340 | void nfprint(const char *fmt, ...) | ||
341 | { | ||
342 | static char buf[256]; | ||
343 | diff --git a/arch/m68k/include/asm/div64.h b/arch/m68k/include/asm/div64.h | ||
344 | index 444ea8a..ef881cf 100644 | ||
345 | --- a/arch/m68k/include/asm/div64.h | ||
346 | +++ b/arch/m68k/include/asm/div64.h | ||
347 | @@ -15,16 +15,17 @@ | ||
348 | unsigned long long n64; \ | ||
349 | } __n; \ | ||
350 | unsigned long __rem, __upper; \ | ||
351 | + unsigned long __base = (base); \ | ||
352 | \ | ||
353 | __n.n64 = (n); \ | ||
354 | if ((__upper = __n.n32[0])) { \ | ||
355 | asm ("divul.l %2,%1:%0" \ | ||
356 | - : "=d" (__n.n32[0]), "=d" (__upper) \ | ||
357 | - : "d" (base), "0" (__n.n32[0])); \ | ||
358 | + : "=d" (__n.n32[0]), "=d" (__upper) \ | ||
359 | + : "d" (__base), "0" (__n.n32[0])); \ | ||
360 | } \ | ||
361 | asm ("divu.l %2,%1:%0" \ | ||
362 | - : "=d" (__n.n32[1]), "=d" (__rem) \ | ||
363 | - : "d" (base), "1" (__upper), "0" (__n.n32[1])); \ | ||
364 | + : "=d" (__n.n32[1]), "=d" (__rem) \ | ||
365 | + : "d" (__base), "1" (__upper), "0" (__n.n32[1])); \ | ||
366 | (n) = __n.n64; \ | ||
367 | __rem; \ | ||
368 | }) | ||
369 | diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig | ||
370 | index d22a4ec..4fab522 100644 | ||
371 | --- a/arch/microblaze/Kconfig | ||
372 | +++ b/arch/microblaze/Kconfig | ||
373 | @@ -28,7 +28,7 @@ config MICROBLAZE | ||
374 | select GENERIC_CLOCKEVENTS | ||
375 | select GENERIC_IDLE_POLL_SETUP | ||
376 | select MODULES_USE_ELF_RELA | ||
377 | - select CLONE_BACKWARDS | ||
378 | + select CLONE_BACKWARDS3 | ||
379 | |||
380 | config SWAP | ||
381 | def_bool n | ||
382 | diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h | ||
383 | index b75d7d6..6d6d92b 100644 | ||
384 | --- a/arch/s390/include/asm/tlb.h | ||
385 | +++ b/arch/s390/include/asm/tlb.h | ||
386 | @@ -32,6 +32,7 @@ struct mmu_gather { | ||
387 | struct mm_struct *mm; | ||
388 | struct mmu_table_batch *batch; | ||
389 | unsigned int fullmm; | ||
390 | + unsigned long start, end; | ||
391 | }; | ||
392 | |||
393 | struct mmu_table_batch { | ||
394 | @@ -48,10 +49,13 @@ extern void tlb_remove_table(struct mmu_gather *tlb, void *table); | ||
395 | |||
396 | static inline void tlb_gather_mmu(struct mmu_gather *tlb, | ||
397 | struct mm_struct *mm, | ||
398 | - unsigned int full_mm_flush) | ||
399 | + unsigned long start, | ||
400 | + unsigned long end) | ||
401 | { | ||
402 | tlb->mm = mm; | ||
403 | - tlb->fullmm = full_mm_flush; | ||
404 | + tlb->start = start; | ||
405 | + tlb->end = end; | ||
406 | + tlb->fullmm = !(start | (end+1)); | ||
407 | tlb->batch = NULL; | ||
408 | if (tlb->fullmm) | ||
409 | __tlb_flush_mm(mm); | ||
410 | diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h | ||
411 | index e61d43d..362192e 100644 | ||
412 | --- a/arch/sh/include/asm/tlb.h | ||
413 | +++ b/arch/sh/include/asm/tlb.h | ||
414 | @@ -36,10 +36,12 @@ static inline void init_tlb_gather(struct mmu_gather *tlb) | ||
415 | } | ||
416 | |||
417 | static inline void | ||
418 | -tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush) | ||
419 | +tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) | ||
420 | { | ||
421 | tlb->mm = mm; | ||
422 | - tlb->fullmm = full_mm_flush; | ||
423 | + tlb->start = start; | ||
424 | + tlb->end = end; | ||
425 | + tlb->fullmm = !(start | (end+1)); | ||
426 | |||
427 | init_tlb_gather(tlb); | ||
428 | } | ||
429 | diff --git a/arch/um/include/asm/tlb.h b/arch/um/include/asm/tlb.h | ||
430 | index 4febacd..29b0301 100644 | ||
431 | --- a/arch/um/include/asm/tlb.h | ||
432 | +++ b/arch/um/include/asm/tlb.h | ||
433 | @@ -45,10 +45,12 @@ static inline void init_tlb_gather(struct mmu_gather *tlb) | ||
434 | } | ||
435 | |||
436 | static inline void | ||
437 | -tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush) | ||
438 | +tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) | ||
439 | { | ||
440 | tlb->mm = mm; | ||
441 | - tlb->fullmm = full_mm_flush; | ||
442 | + tlb->start = start; | ||
443 | + tlb->end = end; | ||
444 | + tlb->fullmm = !(start | (end+1)); | ||
445 | |||
446 | init_tlb_gather(tlb); | ||
447 | } | ||
448 | diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c | ||
449 | index 52441a2..8aac56b 100644 | ||
450 | --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c | ||
451 | +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c | ||
452 | @@ -314,8 +314,8 @@ static struct uncore_event_desc snbep_uncore_imc_events[] = { | ||
453 | static struct uncore_event_desc snbep_uncore_qpi_events[] = { | ||
454 | INTEL_UNCORE_EVENT_DESC(clockticks, "event=0x14"), | ||
455 | INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"), | ||
456 | - INTEL_UNCORE_EVENT_DESC(drs_data, "event=0x02,umask=0x08"), | ||
457 | - INTEL_UNCORE_EVENT_DESC(ncb_data, "event=0x03,umask=0x04"), | ||
458 | + INTEL_UNCORE_EVENT_DESC(drs_data, "event=0x102,umask=0x08"), | ||
459 | + INTEL_UNCORE_EVENT_DESC(ncb_data, "event=0x103,umask=0x04"), | ||
460 | { /* end: all zeroes */ }, | ||
461 | }; | ||
462 | |||
463 | diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c | ||
464 | index dbded5a..48f8375 100644 | ||
465 | --- a/arch/x86/kernel/sys_x86_64.c | ||
466 | +++ b/arch/x86/kernel/sys_x86_64.c | ||
467 | @@ -101,7 +101,7 @@ static void find_start_end(unsigned long flags, unsigned long *begin, | ||
468 | *begin = new_begin; | ||
469 | } | ||
470 | } else { | ||
471 | - *begin = TASK_UNMAPPED_BASE; | ||
472 | + *begin = mmap_legacy_base(); | ||
473 | *end = TASK_SIZE; | ||
474 | } | ||
475 | } | ||
476 | diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c | ||
477 | index 845df68..c1af323 100644 | ||
478 | --- a/arch/x86/mm/mmap.c | ||
479 | +++ b/arch/x86/mm/mmap.c | ||
480 | @@ -98,7 +98,7 @@ static unsigned long mmap_base(void) | ||
481 | * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64 | ||
482 | * does, but not when emulating X86_32 | ||
483 | */ | ||
484 | -static unsigned long mmap_legacy_base(void) | ||
485 | +unsigned long mmap_legacy_base(void) | ||
486 | { | ||
487 | if (mmap_is_ia32()) | ||
488 | return TASK_UNMAPPED_BASE; | ||
489 | diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c | ||
490 | index d5cd313..d5bbdcf 100644 | ||
491 | --- a/block/cfq-iosched.c | ||
492 | +++ b/block/cfq-iosched.c | ||
493 | @@ -4347,18 +4347,28 @@ static void cfq_exit_queue(struct elevator_queue *e) | ||
494 | kfree(cfqd); | ||
495 | } | ||
496 | |||
497 | -static int cfq_init_queue(struct request_queue *q) | ||
498 | +static int cfq_init_queue(struct request_queue *q, struct elevator_type *e) | ||
499 | { | ||
500 | struct cfq_data *cfqd; | ||
501 | struct blkcg_gq *blkg __maybe_unused; | ||
502 | int i, ret; | ||
503 | + struct elevator_queue *eq; | ||
504 | + | ||
505 | + eq = elevator_alloc(q, e); | ||
506 | + if (!eq) | ||
507 | + return -ENOMEM; | ||
508 | |||
509 | cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL | __GFP_ZERO, q->node); | ||
510 | - if (!cfqd) | ||
511 | + if (!cfqd) { | ||
512 | + kobject_put(&eq->kobj); | ||
513 | return -ENOMEM; | ||
514 | + } | ||
515 | + eq->elevator_data = cfqd; | ||
516 | |||
517 | cfqd->queue = q; | ||
518 | - q->elevator->elevator_data = cfqd; | ||
519 | + spin_lock_irq(q->queue_lock); | ||
520 | + q->elevator = eq; | ||
521 | + spin_unlock_irq(q->queue_lock); | ||
522 | |||
523 | /* Init root service tree */ | ||
524 | cfqd->grp_service_tree = CFQ_RB_ROOT; | ||
525 | @@ -4433,6 +4443,7 @@ static int cfq_init_queue(struct request_queue *q) | ||
526 | |||
527 | out_free: | ||
528 | kfree(cfqd); | ||
529 | + kobject_put(&eq->kobj); | ||
530 | return ret; | ||
531 | } | ||
532 | |||
533 | diff --git a/block/deadline-iosched.c b/block/deadline-iosched.c | ||
534 | index ba19a3a..20614a3 100644 | ||
535 | --- a/block/deadline-iosched.c | ||
536 | +++ b/block/deadline-iosched.c | ||
537 | @@ -337,13 +337,21 @@ static void deadline_exit_queue(struct elevator_queue *e) | ||
538 | /* | ||
539 | * initialize elevator private data (deadline_data). | ||
540 | */ | ||
541 | -static int deadline_init_queue(struct request_queue *q) | ||
542 | +static int deadline_init_queue(struct request_queue *q, struct elevator_type *e) | ||
543 | { | ||
544 | struct deadline_data *dd; | ||
545 | + struct elevator_queue *eq; | ||
546 | + | ||
547 | + eq = elevator_alloc(q, e); | ||
548 | + if (!eq) | ||
549 | + return -ENOMEM; | ||
550 | |||
551 | dd = kmalloc_node(sizeof(*dd), GFP_KERNEL | __GFP_ZERO, q->node); | ||
552 | - if (!dd) | ||
553 | + if (!dd) { | ||
554 | + kobject_put(&eq->kobj); | ||
555 | return -ENOMEM; | ||
556 | + } | ||
557 | + eq->elevator_data = dd; | ||
558 | |||
559 | INIT_LIST_HEAD(&dd->fifo_list[READ]); | ||
560 | INIT_LIST_HEAD(&dd->fifo_list[WRITE]); | ||
561 | @@ -355,7 +363,9 @@ static int deadline_init_queue(struct request_queue *q) | ||
562 | dd->front_merges = 1; | ||
563 | dd->fifo_batch = fifo_batch; | ||
564 | |||
565 | - q->elevator->elevator_data = dd; | ||
566 | + spin_lock_irq(q->queue_lock); | ||
567 | + q->elevator = eq; | ||
568 | + spin_unlock_irq(q->queue_lock); | ||
569 | return 0; | ||
570 | } | ||
571 | |||
572 | diff --git a/block/elevator.c b/block/elevator.c | ||
573 | index eba5b04..668394d 100644 | ||
574 | --- a/block/elevator.c | ||
575 | +++ b/block/elevator.c | ||
576 | @@ -150,7 +150,7 @@ void __init load_default_elevator_module(void) | ||
577 | |||
578 | static struct kobj_type elv_ktype; | ||
579 | |||
580 | -static struct elevator_queue *elevator_alloc(struct request_queue *q, | ||
581 | +struct elevator_queue *elevator_alloc(struct request_queue *q, | ||
582 | struct elevator_type *e) | ||
583 | { | ||
584 | struct elevator_queue *eq; | ||
585 | @@ -170,6 +170,7 @@ err: | ||
586 | elevator_put(e); | ||
587 | return NULL; | ||
588 | } | ||
589 | +EXPORT_SYMBOL(elevator_alloc); | ||
590 | |||
591 | static void elevator_release(struct kobject *kobj) | ||
592 | { | ||
593 | @@ -221,16 +222,7 @@ int elevator_init(struct request_queue *q, char *name) | ||
594 | } | ||
595 | } | ||
596 | |||
597 | - q->elevator = elevator_alloc(q, e); | ||
598 | - if (!q->elevator) | ||
599 | - return -ENOMEM; | ||
600 | - | ||
601 | - err = e->ops.elevator_init_fn(q); | ||
602 | - if (err) { | ||
603 | - kobject_put(&q->elevator->kobj); | ||
604 | - return err; | ||
605 | - } | ||
606 | - | ||
607 | + err = e->ops.elevator_init_fn(q, e); | ||
608 | return 0; | ||
609 | } | ||
610 | EXPORT_SYMBOL(elevator_init); | ||
611 | @@ -935,16 +927,9 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e) | ||
612 | spin_unlock_irq(q->queue_lock); | ||
613 | |||
614 | /* allocate, init and register new elevator */ | ||
615 | - err = -ENOMEM; | ||
616 | - q->elevator = elevator_alloc(q, new_e); | ||
617 | - if (!q->elevator) | ||
618 | - goto fail_init; | ||
619 | - | ||
620 | - err = new_e->ops.elevator_init_fn(q); | ||
621 | - if (err) { | ||
622 | - kobject_put(&q->elevator->kobj); | ||
623 | + err = new_e->ops.elevator_init_fn(q, new_e); | ||
624 | + if (err) | ||
625 | goto fail_init; | ||
626 | - } | ||
627 | |||
628 | if (registered) { | ||
629 | err = elv_register_queue(q); | ||
630 | diff --git a/block/noop-iosched.c b/block/noop-iosched.c | ||
631 | index 5d1bf70..3de89d4 100644 | ||
632 | --- a/block/noop-iosched.c | ||
633 | +++ b/block/noop-iosched.c | ||
634 | @@ -59,16 +59,27 @@ noop_latter_request(struct request_queue *q, struct request *rq) | ||
635 | return list_entry(rq->queuelist.next, struct request, queuelist); | ||
636 | } | ||
637 | |||
638 | -static int noop_init_queue(struct request_queue *q) | ||
639 | +static int noop_init_queue(struct request_queue *q, struct elevator_type *e) | ||
640 | { | ||
641 | struct noop_data *nd; | ||
642 | + struct elevator_queue *eq; | ||
643 | + | ||
644 | + eq = elevator_alloc(q, e); | ||
645 | + if (!eq) | ||
646 | + return -ENOMEM; | ||
647 | |||
648 | nd = kmalloc_node(sizeof(*nd), GFP_KERNEL, q->node); | ||
649 | - if (!nd) | ||
650 | + if (!nd) { | ||
651 | + kobject_put(&eq->kobj); | ||
652 | return -ENOMEM; | ||
653 | + } | ||
654 | + eq->elevator_data = nd; | ||
655 | |||
656 | INIT_LIST_HEAD(&nd->queue); | ||
657 | - q->elevator->elevator_data = nd; | ||
658 | + | ||
659 | + spin_lock_irq(q->queue_lock); | ||
660 | + q->elevator = eq; | ||
661 | + spin_unlock_irq(q->queue_lock); | ||
662 | return 0; | ||
663 | } | ||
664 | |||
665 | diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c | ||
666 | index 25723d8..925ab8e 100644 | ||
667 | --- a/drivers/net/can/usb/peak_usb/pcan_usb.c | ||
668 | +++ b/drivers/net/can/usb/peak_usb/pcan_usb.c | ||
669 | @@ -649,7 +649,7 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len) | ||
670 | if ((mc->ptr + rec_len) > mc->end) | ||
671 | goto decode_failed; | ||
672 | |||
673 | - memcpy(cf->data, mc->ptr, rec_len); | ||
674 | + memcpy(cf->data, mc->ptr, cf->can_dlc); | ||
675 | mc->ptr += rec_len; | ||
676 | } | ||
677 | |||
678 | diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c | ||
679 | index 9a95045..900f5f8 100644 | ||
680 | --- a/drivers/net/wireless/iwlegacy/4965-mac.c | ||
681 | +++ b/drivers/net/wireless/iwlegacy/4965-mac.c | ||
682 | @@ -4442,12 +4442,12 @@ il4965_irq_tasklet(struct il_priv *il) | ||
683 | * is killed. Hence update the killswitch state here. The | ||
684 | * rfkill handler will care about restarting if needed. | ||
685 | */ | ||
686 | - if (!test_bit(S_ALIVE, &il->status)) { | ||
687 | - if (hw_rf_kill) | ||
688 | - set_bit(S_RFKILL, &il->status); | ||
689 | - else | ||
690 | - clear_bit(S_RFKILL, &il->status); | ||
691 | + if (hw_rf_kill) { | ||
692 | + set_bit(S_RFKILL, &il->status); | ||
693 | + } else { | ||
694 | + clear_bit(S_RFKILL, &il->status); | ||
695 | wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill); | ||
696 | + il_force_reset(il, true); | ||
697 | } | ||
698 | |||
699 | handled |= CSR_INT_BIT_RF_KILL; | ||
700 | @@ -5316,6 +5316,9 @@ il4965_alive_start(struct il_priv *il) | ||
701 | |||
702 | il->active_rate = RATES_MASK; | ||
703 | |||
704 | + il_power_update_mode(il, true); | ||
705 | + D_INFO("Updated power mode\n"); | ||
706 | + | ||
707 | if (il_is_associated(il)) { | ||
708 | struct il_rxon_cmd *active_rxon = | ||
709 | (struct il_rxon_cmd *)&il->active; | ||
710 | @@ -5346,9 +5349,6 @@ il4965_alive_start(struct il_priv *il) | ||
711 | D_INFO("ALIVE processing complete.\n"); | ||
712 | wake_up(&il->wait_command_queue); | ||
713 | |||
714 | - il_power_update_mode(il, true); | ||
715 | - D_INFO("Updated power mode\n"); | ||
716 | - | ||
717 | return; | ||
718 | |||
719 | restart: | ||
720 | diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c | ||
721 | index e9a3cbc..9c9ebad 100644 | ||
722 | --- a/drivers/net/wireless/iwlegacy/common.c | ||
723 | +++ b/drivers/net/wireless/iwlegacy/common.c | ||
724 | @@ -4660,6 +4660,7 @@ il_force_reset(struct il_priv *il, bool external) | ||
725 | |||
726 | return 0; | ||
727 | } | ||
728 | +EXPORT_SYMBOL(il_force_reset); | ||
729 | |||
730 | int | ||
731 | il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | ||
732 | diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c | ||
733 | index a635988..5b44cd4 100644 | ||
734 | --- a/drivers/usb/core/quirks.c | ||
735 | +++ b/drivers/usb/core/quirks.c | ||
736 | @@ -78,6 +78,12 @@ static const struct usb_device_id usb_quirk_list[] = { | ||
737 | { USB_DEVICE(0x04d8, 0x000c), .driver_info = | ||
738 | USB_QUIRK_CONFIG_INTF_STRINGS }, | ||
739 | |||
740 | + /* CarrolTouch 4000U */ | ||
741 | + { USB_DEVICE(0x04e7, 0x0009), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
742 | + | ||
743 | + /* CarrolTouch 4500U */ | ||
744 | + { USB_DEVICE(0x04e7, 0x0030), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
745 | + | ||
746 | /* Samsung Android phone modem - ID conflict with SPH-I500 */ | ||
747 | { USB_DEVICE(0x04e8, 0x6601), .driver_info = | ||
748 | USB_QUIRK_CONFIG_INTF_STRINGS }, | ||
749 | diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c | ||
750 | index f80d033..8e3c878 100644 | ||
751 | --- a/drivers/usb/host/ehci-sched.c | ||
752 | +++ b/drivers/usb/host/ehci-sched.c | ||
753 | @@ -1391,21 +1391,20 @@ iso_stream_schedule ( | ||
754 | |||
755 | /* Behind the scheduling threshold? */ | ||
756 | if (unlikely(start < next)) { | ||
757 | + unsigned now2 = (now - base) & (mod - 1); | ||
758 | |||
759 | /* USB_ISO_ASAP: Round up to the first available slot */ | ||
760 | if (urb->transfer_flags & URB_ISO_ASAP) | ||
761 | start += (next - start + period - 1) & -period; | ||
762 | |||
763 | /* | ||
764 | - * Not ASAP: Use the next slot in the stream. If | ||
765 | - * the entire URB falls before the threshold, fail. | ||
766 | + * Not ASAP: Use the next slot in the stream, | ||
767 | + * no matter what. | ||
768 | */ | ||
769 | - else if (start + span - period < next) { | ||
770 | - ehci_dbg(ehci, "iso urb late %p (%u+%u < %u)\n", | ||
771 | + else if (start + span - period < now2) { | ||
772 | + ehci_dbg(ehci, "iso underrun %p (%u+%u < %u)\n", | ||
773 | urb, start + base, | ||
774 | - span - period, next + base); | ||
775 | - status = -EXDEV; | ||
776 | - goto fail; | ||
777 | + span - period, now2 + base); | ||
778 | } | ||
779 | } | ||
780 | |||
781 | diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c | ||
782 | index 3549d07..07fbdf0 100644 | ||
783 | --- a/drivers/usb/serial/keyspan.c | ||
784 | +++ b/drivers/usb/serial/keyspan.c | ||
785 | @@ -2315,7 +2315,7 @@ static int keyspan_startup(struct usb_serial *serial) | ||
786 | if (d_details == NULL) { | ||
787 | dev_err(&serial->dev->dev, "%s - unknown product id %x\n", | ||
788 | __func__, le16_to_cpu(serial->dev->descriptor.idProduct)); | ||
789 | - return 1; | ||
790 | + return -ENODEV; | ||
791 | } | ||
792 | |||
793 | /* Setup private data for serial driver */ | ||
794 | diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c | ||
795 | index f27c621..5050cc8 100644 | ||
796 | --- a/drivers/usb/serial/mos7720.c | ||
797 | +++ b/drivers/usb/serial/mos7720.c | ||
798 | @@ -90,6 +90,7 @@ struct urbtracker { | ||
799 | struct list_head urblist_entry; | ||
800 | struct kref ref_count; | ||
801 | struct urb *urb; | ||
802 | + struct usb_ctrlrequest *setup; | ||
803 | }; | ||
804 | |||
805 | enum mos7715_pp_modes { | ||
806 | @@ -271,6 +272,7 @@ static void destroy_urbtracker(struct kref *kref) | ||
807 | struct mos7715_parport *mos_parport = urbtrack->mos_parport; | ||
808 | |||
809 | usb_free_urb(urbtrack->urb); | ||
810 | + kfree(urbtrack->setup); | ||
811 | kfree(urbtrack); | ||
812 | kref_put(&mos_parport->ref_count, destroy_mos_parport); | ||
813 | } | ||
814 | @@ -355,7 +357,6 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, | ||
815 | struct urbtracker *urbtrack; | ||
816 | int ret_val; | ||
817 | unsigned long flags; | ||
818 | - struct usb_ctrlrequest setup; | ||
819 | struct usb_serial *serial = mos_parport->serial; | ||
820 | struct usb_device *usbdev = serial->dev; | ||
821 | |||
822 | @@ -373,14 +374,20 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, | ||
823 | kfree(urbtrack); | ||
824 | return -ENOMEM; | ||
825 | } | ||
826 | - setup.bRequestType = (__u8)0x40; | ||
827 | - setup.bRequest = (__u8)0x0e; | ||
828 | - setup.wValue = get_reg_value(reg, dummy); | ||
829 | - setup.wIndex = get_reg_index(reg); | ||
830 | - setup.wLength = 0; | ||
831 | + urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL); | ||
832 | + if (!urbtrack->setup) { | ||
833 | + usb_free_urb(urbtrack->urb); | ||
834 | + kfree(urbtrack); | ||
835 | + return -ENOMEM; | ||
836 | + } | ||
837 | + urbtrack->setup->bRequestType = (__u8)0x40; | ||
838 | + urbtrack->setup->bRequest = (__u8)0x0e; | ||
839 | + urbtrack->setup->wValue = get_reg_value(reg, dummy); | ||
840 | + urbtrack->setup->wIndex = get_reg_index(reg); | ||
841 | + urbtrack->setup->wLength = 0; | ||
842 | usb_fill_control_urb(urbtrack->urb, usbdev, | ||
843 | usb_sndctrlpipe(usbdev, 0), | ||
844 | - (unsigned char *)&setup, | ||
845 | + (unsigned char *)urbtrack->setup, | ||
846 | NULL, 0, async_complete, urbtrack); | ||
847 | kref_init(&urbtrack->ref_count); | ||
848 | INIT_LIST_HEAD(&urbtrack->urblist_entry); | ||
849 | diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c | ||
850 | index b92d333..2c1749d 100644 | ||
851 | --- a/drivers/usb/serial/mos7840.c | ||
852 | +++ b/drivers/usb/serial/mos7840.c | ||
853 | @@ -2208,7 +2208,7 @@ static int mos7810_check(struct usb_serial *serial) | ||
854 | static int mos7840_probe(struct usb_serial *serial, | ||
855 | const struct usb_device_id *id) | ||
856 | { | ||
857 | - u16 product = serial->dev->descriptor.idProduct; | ||
858 | + u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); | ||
859 | u8 *buf; | ||
860 | int device_type; | ||
861 | |||
862 | diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c | ||
863 | index 01f79f1..32bdd5e 100644 | ||
864 | --- a/drivers/usb/serial/ti_usb_3410_5052.c | ||
865 | +++ b/drivers/usb/serial/ti_usb_3410_5052.c | ||
866 | @@ -1536,14 +1536,15 @@ static int ti_download_firmware(struct ti_device *tdev) | ||
867 | char buf[32]; | ||
868 | |||
869 | /* try ID specific firmware first, then try generic firmware */ | ||
870 | - sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor, | ||
871 | - dev->descriptor.idProduct); | ||
872 | + sprintf(buf, "ti_usb-v%04x-p%04x.fw", | ||
873 | + le16_to_cpu(dev->descriptor.idVendor), | ||
874 | + le16_to_cpu(dev->descriptor.idProduct)); | ||
875 | status = request_firmware(&fw_p, buf, &dev->dev); | ||
876 | |||
877 | if (status != 0) { | ||
878 | buf[0] = '\0'; | ||
879 | - if (dev->descriptor.idVendor == MTS_VENDOR_ID) { | ||
880 | - switch (dev->descriptor.idProduct) { | ||
881 | + if (le16_to_cpu(dev->descriptor.idVendor) == MTS_VENDOR_ID) { | ||
882 | + switch (le16_to_cpu(dev->descriptor.idProduct)) { | ||
883 | case MTS_CDMA_PRODUCT_ID: | ||
884 | strcpy(buf, "mts_cdma.fw"); | ||
885 | break; | ||
886 | diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c | ||
887 | index ece326e..db0cf53 100644 | ||
888 | --- a/drivers/usb/serial/usb_wwan.c | ||
889 | +++ b/drivers/usb/serial/usb_wwan.c | ||
890 | @@ -291,18 +291,18 @@ static void usb_wwan_indat_callback(struct urb *urb) | ||
891 | tty_flip_buffer_push(&port->port); | ||
892 | } else | ||
893 | dev_dbg(dev, "%s: empty read urb received\n", __func__); | ||
894 | - | ||
895 | - /* Resubmit urb so we continue receiving */ | ||
896 | - err = usb_submit_urb(urb, GFP_ATOMIC); | ||
897 | - if (err) { | ||
898 | - if (err != -EPERM) { | ||
899 | - dev_err(dev, "%s: resubmit read urb failed. (%d)\n", __func__, err); | ||
900 | - /* busy also in error unless we are killed */ | ||
901 | - usb_mark_last_busy(port->serial->dev); | ||
902 | - } | ||
903 | - } else { | ||
904 | + } | ||
905 | + /* Resubmit urb so we continue receiving */ | ||
906 | + err = usb_submit_urb(urb, GFP_ATOMIC); | ||
907 | + if (err) { | ||
908 | + if (err != -EPERM) { | ||
909 | + dev_err(dev, "%s: resubmit read urb failed. (%d)\n", | ||
910 | + __func__, err); | ||
911 | + /* busy also in error unless we are killed */ | ||
912 | usb_mark_last_busy(port->serial->dev); | ||
913 | } | ||
914 | + } else { | ||
915 | + usb_mark_last_busy(port->serial->dev); | ||
916 | } | ||
917 | } | ||
918 | |||
919 | diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c | ||
920 | index 6ef94bc..028fc83 100644 | ||
921 | --- a/drivers/usb/wusbcore/wa-xfer.c | ||
922 | +++ b/drivers/usb/wusbcore/wa-xfer.c | ||
923 | @@ -1110,6 +1110,12 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb) | ||
924 | } | ||
925 | spin_lock_irqsave(&xfer->lock, flags); | ||
926 | rpipe = xfer->ep->hcpriv; | ||
927 | + if (rpipe == NULL) { | ||
928 | + pr_debug("%s: xfer id 0x%08X has no RPIPE. %s", | ||
929 | + __func__, wa_xfer_id(xfer), | ||
930 | + "Probably already aborted.\n" ); | ||
931 | + goto out_unlock; | ||
932 | + } | ||
933 | /* Check the delayed list -> if there, release and complete */ | ||
934 | spin_lock_irqsave(&wa->xfer_list_lock, flags2); | ||
935 | if (!list_empty(&xfer->list_node) && xfer->seg == NULL) | ||
936 | @@ -1493,8 +1499,7 @@ static void wa_xfer_result_cb(struct urb *urb) | ||
937 | break; | ||
938 | } | ||
939 | usb_status = xfer_result->bTransferStatus & 0x3f; | ||
940 | - if (usb_status == WA_XFER_STATUS_ABORTED | ||
941 | - || usb_status == WA_XFER_STATUS_NOT_FOUND) | ||
942 | + if (usb_status == WA_XFER_STATUS_NOT_FOUND) | ||
943 | /* taken care of already */ | ||
944 | break; | ||
945 | xfer_id = xfer_result->dwTransferID; | ||
946 | diff --git a/fs/exec.c b/fs/exec.c | ||
947 | index ffd7a81..1f44670 100644 | ||
948 | --- a/fs/exec.c | ||
949 | +++ b/fs/exec.c | ||
950 | @@ -607,7 +607,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) | ||
951 | return -ENOMEM; | ||
952 | |||
953 | lru_add_drain(); | ||
954 | - tlb_gather_mmu(&tlb, mm, 0); | ||
955 | + tlb_gather_mmu(&tlb, mm, old_start, old_end); | ||
956 | if (new_end > old_start) { | ||
957 | /* | ||
958 | * when the old and new regions overlap clear from new_end. | ||
959 | @@ -624,7 +624,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) | ||
960 | free_pgd_range(&tlb, old_start, old_end, new_end, | ||
961 | vma->vm_next ? vma->vm_next->vm_start : USER_PGTABLES_CEILING); | ||
962 | } | ||
963 | - tlb_finish_mmu(&tlb, new_end, old_end); | ||
964 | + tlb_finish_mmu(&tlb, old_start, old_end); | ||
965 | |||
966 | /* | ||
967 | * Shrink the vma to just the new range. Always succeeds. | ||
968 | diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c | ||
969 | index 451eb40..1c88061 100644 | ||
970 | --- a/fs/ext4/ext4_jbd2.c | ||
971 | +++ b/fs/ext4/ext4_jbd2.c | ||
972 | @@ -219,10 +219,10 @@ int __ext4_handle_dirty_metadata(const char *where, unsigned int line, | ||
973 | set_buffer_prio(bh); | ||
974 | if (ext4_handle_valid(handle)) { | ||
975 | err = jbd2_journal_dirty_metadata(handle, bh); | ||
976 | - if (err) { | ||
977 | - /* Errors can only happen if there is a bug */ | ||
978 | - handle->h_err = err; | ||
979 | - __ext4_journal_stop(where, line, handle); | ||
980 | + /* Errors can only happen if there is a bug */ | ||
981 | + if (WARN_ON_ONCE(err)) { | ||
982 | + ext4_journal_abort_handle(where, line, __func__, bh, | ||
983 | + handle, err); | ||
984 | } | ||
985 | } else { | ||
986 | if (inode) | ||
987 | diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c | ||
988 | index 3e636d8..65fc60a 100644 | ||
989 | --- a/fs/proc/task_mmu.c | ||
990 | +++ b/fs/proc/task_mmu.c | ||
991 | @@ -792,14 +792,14 @@ typedef struct { | ||
992 | } pagemap_entry_t; | ||
993 | |||
994 | struct pagemapread { | ||
995 | - int pos, len; | ||
996 | + int pos, len; /* units: PM_ENTRY_BYTES, not bytes */ | ||
997 | pagemap_entry_t *buffer; | ||
998 | }; | ||
999 | |||
1000 | #define PAGEMAP_WALK_SIZE (PMD_SIZE) | ||
1001 | #define PAGEMAP_WALK_MASK (PMD_MASK) | ||
1002 | |||
1003 | -#define PM_ENTRY_BYTES sizeof(u64) | ||
1004 | +#define PM_ENTRY_BYTES sizeof(pagemap_entry_t) | ||
1005 | #define PM_STATUS_BITS 3 | ||
1006 | #define PM_STATUS_OFFSET (64 - PM_STATUS_BITS) | ||
1007 | #define PM_STATUS_MASK (((1LL << PM_STATUS_BITS) - 1) << PM_STATUS_OFFSET) | ||
1008 | @@ -1038,8 +1038,8 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, | ||
1009 | if (!count) | ||
1010 | goto out_task; | ||
1011 | |||
1012 | - pm.len = PM_ENTRY_BYTES * (PAGEMAP_WALK_SIZE >> PAGE_SHIFT); | ||
1013 | - pm.buffer = kmalloc(pm.len, GFP_TEMPORARY); | ||
1014 | + pm.len = (PAGEMAP_WALK_SIZE >> PAGE_SHIFT); | ||
1015 | + pm.buffer = kmalloc(pm.len * PM_ENTRY_BYTES, GFP_TEMPORARY); | ||
1016 | ret = -ENOMEM; | ||
1017 | if (!pm.buffer) | ||
1018 | goto out_task; | ||
1019 | diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h | ||
1020 | index 13821c3..5672d7e 100644 | ||
1021 | --- a/include/asm-generic/tlb.h | ||
1022 | +++ b/include/asm-generic/tlb.h | ||
1023 | @@ -112,7 +112,7 @@ struct mmu_gather { | ||
1024 | |||
1025 | #define HAVE_GENERIC_MMU_GATHER | ||
1026 | |||
1027 | -void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm); | ||
1028 | +void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end); | ||
1029 | void tlb_flush_mmu(struct mmu_gather *tlb); | ||
1030 | void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, | ||
1031 | unsigned long end); | ||
1032 | diff --git a/include/linux/elevator.h b/include/linux/elevator.h | ||
1033 | index acd0312..306dd8c 100644 | ||
1034 | --- a/include/linux/elevator.h | ||
1035 | +++ b/include/linux/elevator.h | ||
1036 | @@ -7,6 +7,7 @@ | ||
1037 | #ifdef CONFIG_BLOCK | ||
1038 | |||
1039 | struct io_cq; | ||
1040 | +struct elevator_type; | ||
1041 | |||
1042 | typedef int (elevator_merge_fn) (struct request_queue *, struct request **, | ||
1043 | struct bio *); | ||
1044 | @@ -35,7 +36,8 @@ typedef void (elevator_put_req_fn) (struct request *); | ||
1045 | typedef void (elevator_activate_req_fn) (struct request_queue *, struct request *); | ||
1046 | typedef void (elevator_deactivate_req_fn) (struct request_queue *, struct request *); | ||
1047 | |||
1048 | -typedef int (elevator_init_fn) (struct request_queue *); | ||
1049 | +typedef int (elevator_init_fn) (struct request_queue *, | ||
1050 | + struct elevator_type *e); | ||
1051 | typedef void (elevator_exit_fn) (struct elevator_queue *); | ||
1052 | |||
1053 | struct elevator_ops | ||
1054 | @@ -155,6 +157,8 @@ extern int elevator_init(struct request_queue *, char *); | ||
1055 | extern void elevator_exit(struct elevator_queue *); | ||
1056 | extern int elevator_change(struct request_queue *, const char *); | ||
1057 | extern bool elv_rq_merge_ok(struct request *, struct bio *); | ||
1058 | +extern struct elevator_queue *elevator_alloc(struct request_queue *, | ||
1059 | + struct elevator_type *); | ||
1060 | |||
1061 | /* | ||
1062 | * Helper functions. | ||
1063 | diff --git a/include/linux/sched.h b/include/linux/sched.h | ||
1064 | index 178a8d9..3aeb14b 100644 | ||
1065 | --- a/include/linux/sched.h | ||
1066 | +++ b/include/linux/sched.h | ||
1067 | @@ -314,6 +314,7 @@ struct nsproxy; | ||
1068 | struct user_namespace; | ||
1069 | |||
1070 | #ifdef CONFIG_MMU | ||
1071 | +extern unsigned long mmap_legacy_base(void); | ||
1072 | extern void arch_pick_mmap_layout(struct mm_struct *mm); | ||
1073 | extern unsigned long | ||
1074 | arch_get_unmapped_area(struct file *, unsigned long, unsigned long, | ||
1075 | diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h | ||
1076 | index 4147d70..84662ec 100644 | ||
1077 | --- a/include/linux/syscalls.h | ||
1078 | +++ b/include/linux/syscalls.h | ||
1079 | @@ -802,9 +802,14 @@ asmlinkage long sys_vfork(void); | ||
1080 | asmlinkage long sys_clone(unsigned long, unsigned long, int __user *, int, | ||
1081 | int __user *); | ||
1082 | #else | ||
1083 | +#ifdef CONFIG_CLONE_BACKWARDS3 | ||
1084 | +asmlinkage long sys_clone(unsigned long, unsigned long, int, int __user *, | ||
1085 | + int __user *, int); | ||
1086 | +#else | ||
1087 | asmlinkage long sys_clone(unsigned long, unsigned long, int __user *, | ||
1088 | int __user *, int); | ||
1089 | #endif | ||
1090 | +#endif | ||
1091 | |||
1092 | asmlinkage long sys_execve(const char __user *filename, | ||
1093 | const char __user *const __user *argv, | ||
1094 | diff --git a/kernel/cpuset.c b/kernel/cpuset.c | ||
1095 | index 64b3f79..6948e94 100644 | ||
1096 | --- a/kernel/cpuset.c | ||
1097 | +++ b/kernel/cpuset.c | ||
1098 | @@ -1502,11 +1502,13 @@ static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val) | ||
1099 | { | ||
1100 | struct cpuset *cs = cgroup_cs(cgrp); | ||
1101 | cpuset_filetype_t type = cft->private; | ||
1102 | - int retval = -ENODEV; | ||
1103 | + int retval = 0; | ||
1104 | |||
1105 | mutex_lock(&cpuset_mutex); | ||
1106 | - if (!is_cpuset_online(cs)) | ||
1107 | + if (!is_cpuset_online(cs)) { | ||
1108 | + retval = -ENODEV; | ||
1109 | goto out_unlock; | ||
1110 | + } | ||
1111 | |||
1112 | switch (type) { | ||
1113 | case FILE_CPU_EXCLUSIVE: | ||
1114 | diff --git a/kernel/fork.c b/kernel/fork.c | ||
1115 | index 987b28a..ffbc090 100644 | ||
1116 | --- a/kernel/fork.c | ||
1117 | +++ b/kernel/fork.c | ||
1118 | @@ -1675,6 +1675,12 @@ SYSCALL_DEFINE5(clone, unsigned long, newsp, unsigned long, clone_flags, | ||
1119 | int __user *, parent_tidptr, | ||
1120 | int __user *, child_tidptr, | ||
1121 | int, tls_val) | ||
1122 | +#elif defined(CONFIG_CLONE_BACKWARDS3) | ||
1123 | +SYSCALL_DEFINE6(clone, unsigned long, clone_flags, unsigned long, newsp, | ||
1124 | + int, stack_size, | ||
1125 | + int __user *, parent_tidptr, | ||
1126 | + int __user *, child_tidptr, | ||
1127 | + int, tls_val) | ||
1128 | #else | ||
1129 | SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, | ||
1130 | int __user *, parent_tidptr, | ||
1131 | diff --git a/kernel/power/qos.c b/kernel/power/qos.c | ||
1132 | index 587ddde..25cf89b 100644 | ||
1133 | --- a/kernel/power/qos.c | ||
1134 | +++ b/kernel/power/qos.c | ||
1135 | @@ -293,6 +293,15 @@ int pm_qos_request_active(struct pm_qos_request *req) | ||
1136 | } | ||
1137 | EXPORT_SYMBOL_GPL(pm_qos_request_active); | ||
1138 | |||
1139 | +static void __pm_qos_update_request(struct pm_qos_request *req, | ||
1140 | + s32 new_value) | ||
1141 | +{ | ||
1142 | + if (new_value != req->node.prio) | ||
1143 | + pm_qos_update_target( | ||
1144 | + pm_qos_array[req->pm_qos_class]->constraints, | ||
1145 | + &req->node, PM_QOS_UPDATE_REQ, new_value); | ||
1146 | +} | ||
1147 | + | ||
1148 | /** | ||
1149 | * pm_qos_work_fn - the timeout handler of pm_qos_update_request_timeout | ||
1150 | * @work: work struct for the delayed work (timeout) | ||
1151 | @@ -305,7 +314,7 @@ static void pm_qos_work_fn(struct work_struct *work) | ||
1152 | struct pm_qos_request, | ||
1153 | work); | ||
1154 | |||
1155 | - pm_qos_update_request(req, PM_QOS_DEFAULT_VALUE); | ||
1156 | + __pm_qos_update_request(req, PM_QOS_DEFAULT_VALUE); | ||
1157 | } | ||
1158 | |||
1159 | /** | ||
1160 | @@ -365,6 +374,8 @@ void pm_qos_update_request(struct pm_qos_request *req, | ||
1161 | pm_qos_update_target( | ||
1162 | pm_qos_array[req->pm_qos_class]->constraints, | ||
1163 | &req->node, PM_QOS_UPDATE_REQ, new_value); | ||
1164 | + | ||
1165 | + __pm_qos_update_request(req, new_value); | ||
1166 | } | ||
1167 | EXPORT_SYMBOL_GPL(pm_qos_update_request); | ||
1168 | |||
1169 | diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c | ||
1170 | index c61a614..03b73be 100644 | ||
1171 | --- a/kernel/sched/fair.c | ||
1172 | +++ b/kernel/sched/fair.c | ||
1173 | @@ -1984,6 +1984,7 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued) | ||
1174 | */ | ||
1175 | update_entity_load_avg(curr, 1); | ||
1176 | update_cfs_rq_blocked_load(cfs_rq, 1); | ||
1177 | + update_cfs_shares(cfs_rq); | ||
1178 | |||
1179 | #ifdef CONFIG_SCHED_HRTICK | ||
1180 | /* | ||
1181 | diff --git a/mm/hugetlb.c b/mm/hugetlb.c | ||
1182 | index 5cf99bf..7c5eb85 100644 | ||
1183 | --- a/mm/hugetlb.c | ||
1184 | +++ b/mm/hugetlb.c | ||
1185 | @@ -2490,7 +2490,7 @@ void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, | ||
1186 | |||
1187 | mm = vma->vm_mm; | ||
1188 | |||
1189 | - tlb_gather_mmu(&tlb, mm, 0); | ||
1190 | + tlb_gather_mmu(&tlb, mm, start, end); | ||
1191 | __unmap_hugepage_range(&tlb, vma, start, end, ref_page); | ||
1192 | tlb_finish_mmu(&tlb, start, end); | ||
1193 | } | ||
1194 | diff --git a/mm/memcontrol.c b/mm/memcontrol.c | ||
1195 | index 15b0409..82a187a 100644 | ||
1196 | --- a/mm/memcontrol.c | ||
1197 | +++ b/mm/memcontrol.c | ||
1198 | @@ -3186,11 +3186,11 @@ int memcg_register_cache(struct mem_cgroup *memcg, struct kmem_cache *s, | ||
1199 | if (!s->memcg_params) | ||
1200 | return -ENOMEM; | ||
1201 | |||
1202 | - INIT_WORK(&s->memcg_params->destroy, | ||
1203 | - kmem_cache_destroy_work_func); | ||
1204 | if (memcg) { | ||
1205 | s->memcg_params->memcg = memcg; | ||
1206 | s->memcg_params->root_cache = root_cache; | ||
1207 | + INIT_WORK(&s->memcg_params->destroy, | ||
1208 | + kmem_cache_destroy_work_func); | ||
1209 | } else | ||
1210 | s->memcg_params->is_root_cache = true; | ||
1211 | |||
1212 | diff --git a/mm/memory.c b/mm/memory.c | ||
1213 | index 5e50800..5a35443 100644 | ||
1214 | --- a/mm/memory.c | ||
1215 | +++ b/mm/memory.c | ||
1216 | @@ -211,14 +211,15 @@ static int tlb_next_batch(struct mmu_gather *tlb) | ||
1217 | * tear-down from @mm. The @fullmm argument is used when @mm is without | ||
1218 | * users and we're going to destroy the full address space (exit/execve). | ||
1219 | */ | ||
1220 | -void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm) | ||
1221 | +void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) | ||
1222 | { | ||
1223 | tlb->mm = mm; | ||
1224 | |||
1225 | - tlb->fullmm = fullmm; | ||
1226 | + /* Is it from 0 to ~0? */ | ||
1227 | + tlb->fullmm = !(start | (end+1)); | ||
1228 | tlb->need_flush_all = 0; | ||
1229 | - tlb->start = -1UL; | ||
1230 | - tlb->end = 0; | ||
1231 | + tlb->start = start; | ||
1232 | + tlb->end = end; | ||
1233 | tlb->need_flush = 0; | ||
1234 | tlb->local.next = NULL; | ||
1235 | tlb->local.nr = 0; | ||
1236 | @@ -258,8 +259,6 @@ void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long e | ||
1237 | { | ||
1238 | struct mmu_gather_batch *batch, *next; | ||
1239 | |||
1240 | - tlb->start = start; | ||
1241 | - tlb->end = end; | ||
1242 | tlb_flush_mmu(tlb); | ||
1243 | |||
1244 | /* keep the page table cache within bounds */ | ||
1245 | @@ -1101,7 +1100,6 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb, | ||
1246 | spinlock_t *ptl; | ||
1247 | pte_t *start_pte; | ||
1248 | pte_t *pte; | ||
1249 | - unsigned long range_start = addr; | ||
1250 | |||
1251 | again: | ||
1252 | init_rss_vec(rss); | ||
1253 | @@ -1204,17 +1202,25 @@ again: | ||
1254 | * and page-free while holding it. | ||
1255 | */ | ||
1256 | if (force_flush) { | ||
1257 | + unsigned long old_end; | ||
1258 | + | ||
1259 | force_flush = 0; | ||
1260 | |||
1261 | -#ifdef HAVE_GENERIC_MMU_GATHER | ||
1262 | - tlb->start = range_start; | ||
1263 | + /* | ||
1264 | + * Flush the TLB just for the previous segment, | ||
1265 | + * then update the range to be the remaining | ||
1266 | + * TLB range. | ||
1267 | + */ | ||
1268 | + old_end = tlb->end; | ||
1269 | tlb->end = addr; | ||
1270 | -#endif | ||
1271 | + | ||
1272 | tlb_flush_mmu(tlb); | ||
1273 | - if (addr != end) { | ||
1274 | - range_start = addr; | ||
1275 | + | ||
1276 | + tlb->start = addr; | ||
1277 | + tlb->end = old_end; | ||
1278 | + | ||
1279 | + if (addr != end) | ||
1280 | goto again; | ||
1281 | - } | ||
1282 | } | ||
1283 | |||
1284 | return addr; | ||
1285 | @@ -1399,7 +1405,7 @@ void zap_page_range(struct vm_area_struct *vma, unsigned long start, | ||
1286 | unsigned long end = start + size; | ||
1287 | |||
1288 | lru_add_drain(); | ||
1289 | - tlb_gather_mmu(&tlb, mm, 0); | ||
1290 | + tlb_gather_mmu(&tlb, mm, start, end); | ||
1291 | update_hiwater_rss(mm); | ||
1292 | mmu_notifier_invalidate_range_start(mm, start, end); | ||
1293 | for ( ; vma && vma->vm_start < end; vma = vma->vm_next) | ||
1294 | @@ -1425,7 +1431,7 @@ static void zap_page_range_single(struct vm_area_struct *vma, unsigned long addr | ||
1295 | unsigned long end = address + size; | ||
1296 | |||
1297 | lru_add_drain(); | ||
1298 | - tlb_gather_mmu(&tlb, mm, 0); | ||
1299 | + tlb_gather_mmu(&tlb, mm, address, end); | ||
1300 | update_hiwater_rss(mm); | ||
1301 | mmu_notifier_invalidate_range_start(mm, address, end); | ||
1302 | unmap_single_vma(&tlb, vma, address, end, details); | ||
1303 | diff --git a/mm/mmap.c b/mm/mmap.c | ||
1304 | index 7dbe397..8d25fdc 100644 | ||
1305 | --- a/mm/mmap.c | ||
1306 | +++ b/mm/mmap.c | ||
1307 | @@ -2356,7 +2356,7 @@ static void unmap_region(struct mm_struct *mm, | ||
1308 | struct mmu_gather tlb; | ||
1309 | |||
1310 | lru_add_drain(); | ||
1311 | - tlb_gather_mmu(&tlb, mm, 0); | ||
1312 | + tlb_gather_mmu(&tlb, mm, start, end); | ||
1313 | update_hiwater_rss(mm); | ||
1314 | unmap_vmas(&tlb, vma, start, end); | ||
1315 | free_pgtables(&tlb, vma, prev ? prev->vm_end : FIRST_USER_ADDRESS, | ||
1316 | @@ -2735,7 +2735,7 @@ void exit_mmap(struct mm_struct *mm) | ||
1317 | |||
1318 | lru_add_drain(); | ||
1319 | flush_cache_mm(mm); | ||
1320 | - tlb_gather_mmu(&tlb, mm, 1); | ||
1321 | + tlb_gather_mmu(&tlb, mm, 0, -1); | ||
1322 | /* update_hiwater_rss(mm) here? but nobody should be looking */ | ||
1323 | /* Use -1 here to ensure all VMAs in the mm are unmapped */ | ||
1324 | unmap_vmas(&tlb, vma, 0, -1); | ||
1325 | diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c | ||
1326 | index 741448b..55a42f9 100644 | ||
1327 | --- a/net/mac80211/mlme.c | ||
1328 | +++ b/net/mac80211/mlme.c | ||
1329 | @@ -237,8 +237,9 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, | ||
1330 | struct ieee80211_channel *channel, | ||
1331 | const struct ieee80211_ht_operation *ht_oper, | ||
1332 | const struct ieee80211_vht_operation *vht_oper, | ||
1333 | - struct cfg80211_chan_def *chandef, bool verbose) | ||
1334 | + struct cfg80211_chan_def *chandef, bool tracking) | ||
1335 | { | ||
1336 | + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
1337 | struct cfg80211_chan_def vht_chandef; | ||
1338 | u32 ht_cfreq, ret; | ||
1339 | |||
1340 | @@ -257,7 +258,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, | ||
1341 | ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan, | ||
1342 | channel->band); | ||
1343 | /* check that channel matches the right operating channel */ | ||
1344 | - if (channel->center_freq != ht_cfreq) { | ||
1345 | + if (!tracking && channel->center_freq != ht_cfreq) { | ||
1346 | /* | ||
1347 | * It's possible that some APs are confused here; | ||
1348 | * Netgear WNDR3700 sometimes reports 4 higher than | ||
1349 | @@ -265,11 +266,10 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, | ||
1350 | * since we look at probe response/beacon data here | ||
1351 | * it should be OK. | ||
1352 | */ | ||
1353 | - if (verbose) | ||
1354 | - sdata_info(sdata, | ||
1355 | - "Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n", | ||
1356 | - channel->center_freq, ht_cfreq, | ||
1357 | - ht_oper->primary_chan, channel->band); | ||
1358 | + sdata_info(sdata, | ||
1359 | + "Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n", | ||
1360 | + channel->center_freq, ht_cfreq, | ||
1361 | + ht_oper->primary_chan, channel->band); | ||
1362 | ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT; | ||
1363 | goto out; | ||
1364 | } | ||
1365 | @@ -323,7 +323,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, | ||
1366 | channel->band); | ||
1367 | break; | ||
1368 | default: | ||
1369 | - if (verbose) | ||
1370 | + if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) | ||
1371 | sdata_info(sdata, | ||
1372 | "AP VHT operation IE has invalid channel width (%d), disable VHT\n", | ||
1373 | vht_oper->chan_width); | ||
1374 | @@ -332,7 +332,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, | ||
1375 | } | ||
1376 | |||
1377 | if (!cfg80211_chandef_valid(&vht_chandef)) { | ||
1378 | - if (verbose) | ||
1379 | + if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) | ||
1380 | sdata_info(sdata, | ||
1381 | "AP VHT information is invalid, disable VHT\n"); | ||
1382 | ret = IEEE80211_STA_DISABLE_VHT; | ||
1383 | @@ -345,7 +345,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, | ||
1384 | } | ||
1385 | |||
1386 | if (!cfg80211_chandef_compatible(chandef, &vht_chandef)) { | ||
1387 | - if (verbose) | ||
1388 | + if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) | ||
1389 | sdata_info(sdata, | ||
1390 | "AP VHT information doesn't match HT, disable VHT\n"); | ||
1391 | ret = IEEE80211_STA_DISABLE_VHT; | ||
1392 | @@ -361,18 +361,27 @@ out: | ||
1393 | if (ret & IEEE80211_STA_DISABLE_VHT) | ||
1394 | vht_chandef = *chandef; | ||
1395 | |||
1396 | + /* | ||
1397 | + * Ignore the DISABLED flag when we're already connected and only | ||
1398 | + * tracking the APs beacon for bandwidth changes - otherwise we | ||
1399 | + * might get disconnected here if we connect to an AP, update our | ||
1400 | + * regulatory information based on the AP's country IE and the | ||
1401 | + * information we have is wrong/outdated and disables the channel | ||
1402 | + * that we're actually using for the connection to the AP. | ||
1403 | + */ | ||
1404 | while (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef, | ||
1405 | - IEEE80211_CHAN_DISABLED)) { | ||
1406 | + tracking ? 0 : | ||
1407 | + IEEE80211_CHAN_DISABLED)) { | ||
1408 | if (WARN_ON(chandef->width == NL80211_CHAN_WIDTH_20_NOHT)) { | ||
1409 | ret = IEEE80211_STA_DISABLE_HT | | ||
1410 | IEEE80211_STA_DISABLE_VHT; | ||
1411 | - goto out; | ||
1412 | + break; | ||
1413 | } | ||
1414 | |||
1415 | ret |= chandef_downgrade(chandef); | ||
1416 | } | ||
1417 | |||
1418 | - if (chandef->width != vht_chandef.width && verbose) | ||
1419 | + if (chandef->width != vht_chandef.width && !tracking) | ||
1420 | sdata_info(sdata, | ||
1421 | "capabilities/regulatory prevented using AP HT/VHT configuration, downgraded\n"); | ||
1422 | |||
1423 | @@ -412,7 +421,7 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata, | ||
1424 | |||
1425 | /* calculate new channel (type) based on HT/VHT operation IEs */ | ||
1426 | flags = ieee80211_determine_chantype(sdata, sband, chan, ht_oper, | ||
1427 | - vht_oper, &chandef, false); | ||
1428 | + vht_oper, &chandef, true); | ||
1429 | |||
1430 | /* | ||
1431 | * Downgrade the new channel if we associated with restricted | ||
1432 | @@ -3906,7 +3915,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, | ||
1433 | ifmgd->flags |= ieee80211_determine_chantype(sdata, sband, | ||
1434 | cbss->channel, | ||
1435 | ht_oper, vht_oper, | ||
1436 | - &chandef, true); | ||
1437 | + &chandef, false); | ||
1438 | |||
1439 | sdata->needed_rx_chains = min(ieee80211_ht_vht_rx_chains(sdata, cbss), | ||
1440 | local->rx_chains); | ||
1441 | diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c | ||
1442 | index 1076fe1..ba6e55d 100644 | ||
1443 | --- a/net/netlink/genetlink.c | ||
1444 | +++ b/net/netlink/genetlink.c | ||
1445 | @@ -789,6 +789,10 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb) | ||
1446 | struct net *net = sock_net(skb->sk); | ||
1447 | int chains_to_skip = cb->args[0]; | ||
1448 | int fams_to_skip = cb->args[1]; | ||
1449 | + bool need_locking = chains_to_skip || fams_to_skip; | ||
1450 | + | ||
1451 | + if (need_locking) | ||
1452 | + genl_lock(); | ||
1453 | |||
1454 | for (i = chains_to_skip; i < GENL_FAM_TAB_SIZE; i++) { | ||
1455 | n = 0; | ||
1456 | @@ -810,6 +814,9 @@ errout: | ||
1457 | cb->args[0] = i; | ||
1458 | cb->args[1] = n; | ||
1459 | |||
1460 | + if (need_locking) | ||
1461 | + genl_unlock(); | ||
1462 | + | ||
1463 | return skb->len; | ||
1464 | } | ||
1465 | |||
1466 | diff --git a/net/wireless/core.c b/net/wireless/core.c | ||
1467 | index 73405e0..64fcbae 100644 | ||
1468 | --- a/net/wireless/core.c | ||
1469 | +++ b/net/wireless/core.c | ||
1470 | @@ -876,6 +876,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev, | ||
1471 | cfg80211_leave_mesh(rdev, dev); | ||
1472 | break; | ||
1473 | case NL80211_IFTYPE_AP: | ||
1474 | + case NL80211_IFTYPE_P2P_GO: | ||
1475 | cfg80211_stop_ap(rdev, dev); | ||
1476 | break; | ||
1477 | default: | ||
1478 | diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c | ||
1479 | index db8ead9..448c034 100644 | ||
1480 | --- a/net/wireless/nl80211.c | ||
1481 | +++ b/net/wireless/nl80211.c | ||
1482 | @@ -471,10 +471,12 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb, | ||
1483 | goto out_unlock; | ||
1484 | } | ||
1485 | *rdev = wiphy_to_dev((*wdev)->wiphy); | ||
1486 | - cb->args[0] = (*rdev)->wiphy_idx; | ||
1487 | + /* 0 is the first index - add 1 to parse only once */ | ||
1488 | + cb->args[0] = (*rdev)->wiphy_idx + 1; | ||
1489 | cb->args[1] = (*wdev)->identifier; | ||
1490 | } else { | ||
1491 | - struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0]); | ||
1492 | + /* subtract the 1 again here */ | ||
1493 | + struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1); | ||
1494 | struct wireless_dev *tmp; | ||
1495 | |||
1496 | if (!wiphy) { | ||
1497 | diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c | ||
1498 | index 24400cf..ad22dec 100644 | ||
1499 | --- a/sound/pci/hda/hda_generic.c | ||
1500 | +++ b/sound/pci/hda/hda_generic.c | ||
1501 | @@ -519,7 +519,7 @@ static bool same_amp_caps(struct hda_codec *codec, hda_nid_t nid1, | ||
1502 | } | ||
1503 | |||
1504 | #define nid_has_mute(codec, nid, dir) \ | ||
1505 | - check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE) | ||
1506 | + check_amp_caps(codec, nid, dir, (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)) | ||
1507 | #define nid_has_volume(codec, nid, dir) \ | ||
1508 | check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS) | ||
1509 | |||
1510 | @@ -621,7 +621,7 @@ static int get_amp_val_to_activate(struct hda_codec *codec, hda_nid_t nid, | ||
1511 | if (enable) | ||
1512 | val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; | ||
1513 | } | ||
1514 | - if (caps & AC_AMPCAP_MUTE) { | ||
1515 | + if (caps & (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)) { | ||
1516 | if (!enable) | ||
1517 | val |= HDA_AMP_MUTE; | ||
1518 | } | ||
1519 | @@ -645,7 +645,7 @@ static unsigned int get_amp_mask_to_modify(struct hda_codec *codec, | ||
1520 | { | ||
1521 | unsigned int mask = 0xff; | ||
1522 | |||
1523 | - if (caps & AC_AMPCAP_MUTE) { | ||
1524 | + if (caps & (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)) { | ||
1525 | if (is_ctl_associated(codec, nid, dir, idx, NID_PATH_MUTE_CTL)) | ||
1526 | mask &= ~0x80; | ||
1527 | } | ||
1528 | diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c | ||
1529 | index 051c03d..57f9f2a 100644 | ||
1530 | --- a/sound/pci/hda/patch_realtek.c | ||
1531 | +++ b/sound/pci/hda/patch_realtek.c | ||
1532 | @@ -1027,6 +1027,7 @@ enum { | ||
1533 | ALC880_FIXUP_GPIO2, | ||
1534 | ALC880_FIXUP_MEDION_RIM, | ||
1535 | ALC880_FIXUP_LG, | ||
1536 | + ALC880_FIXUP_LG_LW25, | ||
1537 | ALC880_FIXUP_W810, | ||
1538 | ALC880_FIXUP_EAPD_COEF, | ||
1539 | ALC880_FIXUP_TCL_S700, | ||
1540 | @@ -1085,6 +1086,14 @@ static const struct hda_fixup alc880_fixups[] = { | ||
1541 | { } | ||
1542 | } | ||
1543 | }, | ||
1544 | + [ALC880_FIXUP_LG_LW25] = { | ||
1545 | + .type = HDA_FIXUP_PINS, | ||
1546 | + .v.pins = (const struct hda_pintbl[]) { | ||
1547 | + { 0x1a, 0x0181344f }, /* line-in */ | ||
1548 | + { 0x1b, 0x0321403f }, /* headphone */ | ||
1549 | + { } | ||
1550 | + } | ||
1551 | + }, | ||
1552 | [ALC880_FIXUP_W810] = { | ||
1553 | .type = HDA_FIXUP_PINS, | ||
1554 | .v.pins = (const struct hda_pintbl[]) { | ||
1555 | @@ -1337,6 +1346,7 @@ static const struct snd_pci_quirk alc880_fixup_tbl[] = { | ||
1556 | SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG), | ||
1557 | SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG), | ||
1558 | SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG), | ||
1559 | + SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25), | ||
1560 | SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700), | ||
1561 | |||
1562 | /* Below is the copied entries from alc880_quirks.c. | ||
1563 | @@ -4200,6 +4210,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { | ||
1564 | SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), | ||
1565 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), | ||
1566 | SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), | ||
1567 | + SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC), | ||
1568 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), | ||
1569 | SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | ||
1570 | SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | ||
1571 | diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c | ||
1572 | index 987f728..ee25f32 100644 | ||
1573 | --- a/sound/soc/codecs/cs42l52.c | ||
1574 | +++ b/sound/soc/codecs/cs42l52.c | ||
1575 | @@ -451,7 +451,7 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = { | ||
1576 | SOC_ENUM("Beep Pitch", beep_pitch_enum), | ||
1577 | SOC_ENUM("Beep on Time", beep_ontime_enum), | ||
1578 | SOC_ENUM("Beep off Time", beep_offtime_enum), | ||
1579 | - SOC_SINGLE_TLV("Beep Volume", CS42L52_BEEP_VOL, 0, 0x1f, 0x07, hl_tlv), | ||
1580 | + SOC_SINGLE_SX_TLV("Beep Volume", CS42L52_BEEP_VOL, 0, 0x07, 0x1f, hl_tlv), | ||
1581 | SOC_SINGLE("Beep Mixer Switch", CS42L52_BEEP_TONE_CTL, 5, 1, 1), | ||
1582 | SOC_ENUM("Beep Treble Corner Freq", beep_treble_enum), | ||
1583 | SOC_ENUM("Beep Bass Corner Freq", beep_bass_enum), | ||
1584 | diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c | ||
1585 | index c7051c4..3606383 100644 | ||
1586 | --- a/sound/soc/soc-dapm.c | ||
1587 | +++ b/sound/soc/soc-dapm.c | ||
1588 | @@ -682,13 +682,14 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w) | ||
1589 | return -EINVAL; | ||
1590 | } | ||
1591 | |||
1592 | - path = list_first_entry(&w->sources, struct snd_soc_dapm_path, | ||
1593 | - list_sink); | ||
1594 | - if (!path) { | ||
1595 | + if (list_empty(&w->sources)) { | ||
1596 | dev_err(dapm->dev, "ASoC: mux %s has no paths\n", w->name); | ||
1597 | return -EINVAL; | ||
1598 | } | ||
1599 | |||
1600 | + path = list_first_entry(&w->sources, struct snd_soc_dapm_path, | ||
1601 | + list_sink); | ||
1602 | + | ||
1603 | ret = dapm_create_or_share_mixmux_kcontrol(w, 0, path); | ||
1604 | if (ret < 0) | ||
1605 | return ret; | ||
1606 | diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c | ||
1607 | index 31d092d..a5432b1 100644 | ||
1608 | --- a/sound/soc/tegra/tegra30_i2s.c | ||
1609 | +++ b/sound/soc/tegra/tegra30_i2s.c | ||
1610 | @@ -228,7 +228,7 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, | ||
1611 | reg = TEGRA30_I2S_CIF_RX_CTRL; | ||
1612 | } else { | ||
1613 | val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX; | ||
1614 | - reg = TEGRA30_I2S_CIF_RX_CTRL; | ||
1615 | + reg = TEGRA30_I2S_CIF_TX_CTRL; | ||
1616 | } | ||
1617 | |||
1618 | regmap_write(i2s->regmap, reg, val); | ||
1619 | diff --git a/sound/usb/6fire/midi.c b/sound/usb/6fire/midi.c | ||
1620 | index 2672242..f3dd726 100644 | ||
1621 | --- a/sound/usb/6fire/midi.c | ||
1622 | +++ b/sound/usb/6fire/midi.c | ||
1623 | @@ -19,6 +19,10 @@ | ||
1624 | #include "chip.h" | ||
1625 | #include "comm.h" | ||
1626 | |||
1627 | +enum { | ||
1628 | + MIDI_BUFSIZE = 64 | ||
1629 | +}; | ||
1630 | + | ||
1631 | static void usb6fire_midi_out_handler(struct urb *urb) | ||
1632 | { | ||
1633 | struct midi_runtime *rt = urb->context; | ||
1634 | @@ -156,6 +160,12 @@ int usb6fire_midi_init(struct sfire_chip *chip) | ||
1635 | if (!rt) | ||
1636 | return -ENOMEM; | ||
1637 | |||
1638 | + rt->out_buffer = kzalloc(MIDI_BUFSIZE, GFP_KERNEL); | ||
1639 | + if (!rt->out_buffer) { | ||
1640 | + kfree(rt); | ||
1641 | + return -ENOMEM; | ||
1642 | + } | ||
1643 | + | ||
1644 | rt->chip = chip; | ||
1645 | rt->in_received = usb6fire_midi_in_received; | ||
1646 | rt->out_buffer[0] = 0x80; /* 'send midi' command */ | ||
1647 | @@ -169,6 +179,7 @@ int usb6fire_midi_init(struct sfire_chip *chip) | ||
1648 | |||
1649 | ret = snd_rawmidi_new(chip->card, "6FireUSB", 0, 1, 1, &rt->instance); | ||
1650 | if (ret < 0) { | ||
1651 | + kfree(rt->out_buffer); | ||
1652 | kfree(rt); | ||
1653 | snd_printk(KERN_ERR PREFIX "unable to create midi.\n"); | ||
1654 | return ret; | ||
1655 | @@ -197,6 +208,9 @@ void usb6fire_midi_abort(struct sfire_chip *chip) | ||
1656 | |||
1657 | void usb6fire_midi_destroy(struct sfire_chip *chip) | ||
1658 | { | ||
1659 | - kfree(chip->midi); | ||
1660 | + struct midi_runtime *rt = chip->midi; | ||
1661 | + | ||
1662 | + kfree(rt->out_buffer); | ||
1663 | + kfree(rt); | ||
1664 | chip->midi = NULL; | ||
1665 | } | ||
1666 | diff --git a/sound/usb/6fire/midi.h b/sound/usb/6fire/midi.h | ||
1667 | index c321006..84851b9 100644 | ||
1668 | --- a/sound/usb/6fire/midi.h | ||
1669 | +++ b/sound/usb/6fire/midi.h | ||
1670 | @@ -16,10 +16,6 @@ | ||
1671 | |||
1672 | #include "common.h" | ||
1673 | |||
1674 | -enum { | ||
1675 | - MIDI_BUFSIZE = 64 | ||
1676 | -}; | ||
1677 | - | ||
1678 | struct midi_runtime { | ||
1679 | struct sfire_chip *chip; | ||
1680 | struct snd_rawmidi *instance; | ||
1681 | @@ -32,7 +28,7 @@ struct midi_runtime { | ||
1682 | struct snd_rawmidi_substream *out; | ||
1683 | struct urb out_urb; | ||
1684 | u8 out_serial; /* serial number of out packet */ | ||
1685 | - u8 out_buffer[MIDI_BUFSIZE]; | ||
1686 | + u8 *out_buffer; | ||
1687 | int buffer_offset; | ||
1688 | |||
1689 | void (*in_received)(struct midi_runtime *rt, u8 *data, int length); | ||
1690 | diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c | ||
1691 | index 074aaf7..25f9e61 100644 | ||
1692 | --- a/sound/usb/6fire/pcm.c | ||
1693 | +++ b/sound/usb/6fire/pcm.c | ||
1694 | @@ -580,6 +580,33 @@ static void usb6fire_pcm_init_urb(struct pcm_urb *urb, | ||
1695 | urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB; | ||
1696 | } | ||
1697 | |||
1698 | +static int usb6fire_pcm_buffers_init(struct pcm_runtime *rt) | ||
1699 | +{ | ||
1700 | + int i; | ||
1701 | + | ||
1702 | + for (i = 0; i < PCM_N_URBS; i++) { | ||
1703 | + rt->out_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB | ||
1704 | + * PCM_MAX_PACKET_SIZE, GFP_KERNEL); | ||
1705 | + if (!rt->out_urbs[i].buffer) | ||
1706 | + return -ENOMEM; | ||
1707 | + rt->in_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB | ||
1708 | + * PCM_MAX_PACKET_SIZE, GFP_KERNEL); | ||
1709 | + if (!rt->in_urbs[i].buffer) | ||
1710 | + return -ENOMEM; | ||
1711 | + } | ||
1712 | + return 0; | ||
1713 | +} | ||
1714 | + | ||
1715 | +static void usb6fire_pcm_buffers_destroy(struct pcm_runtime *rt) | ||
1716 | +{ | ||
1717 | + int i; | ||
1718 | + | ||
1719 | + for (i = 0; i < PCM_N_URBS; i++) { | ||
1720 | + kfree(rt->out_urbs[i].buffer); | ||
1721 | + kfree(rt->in_urbs[i].buffer); | ||
1722 | + } | ||
1723 | +} | ||
1724 | + | ||
1725 | int usb6fire_pcm_init(struct sfire_chip *chip) | ||
1726 | { | ||
1727 | int i; | ||
1728 | @@ -591,6 +618,13 @@ int usb6fire_pcm_init(struct sfire_chip *chip) | ||
1729 | if (!rt) | ||
1730 | return -ENOMEM; | ||
1731 | |||
1732 | + ret = usb6fire_pcm_buffers_init(rt); | ||
1733 | + if (ret) { | ||
1734 | + usb6fire_pcm_buffers_destroy(rt); | ||
1735 | + kfree(rt); | ||
1736 | + return ret; | ||
1737 | + } | ||
1738 | + | ||
1739 | rt->chip = chip; | ||
1740 | rt->stream_state = STREAM_DISABLED; | ||
1741 | rt->rate = ARRAY_SIZE(rates); | ||
1742 | @@ -612,6 +646,7 @@ int usb6fire_pcm_init(struct sfire_chip *chip) | ||
1743 | |||
1744 | ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm); | ||
1745 | if (ret < 0) { | ||
1746 | + usb6fire_pcm_buffers_destroy(rt); | ||
1747 | kfree(rt); | ||
1748 | snd_printk(KERN_ERR PREFIX "cannot create pcm instance.\n"); | ||
1749 | return ret; | ||
1750 | @@ -627,6 +662,7 @@ int usb6fire_pcm_init(struct sfire_chip *chip) | ||
1751 | snd_dma_continuous_data(GFP_KERNEL), | ||
1752 | MAX_BUFSIZE, MAX_BUFSIZE); | ||
1753 | if (ret) { | ||
1754 | + usb6fire_pcm_buffers_destroy(rt); | ||
1755 | kfree(rt); | ||
1756 | snd_printk(KERN_ERR PREFIX | ||
1757 | "error preallocating pcm buffers.\n"); | ||
1758 | @@ -671,6 +707,9 @@ void usb6fire_pcm_abort(struct sfire_chip *chip) | ||
1759 | |||
1760 | void usb6fire_pcm_destroy(struct sfire_chip *chip) | ||
1761 | { | ||
1762 | - kfree(chip->pcm); | ||
1763 | + struct pcm_runtime *rt = chip->pcm; | ||
1764 | + | ||
1765 | + usb6fire_pcm_buffers_destroy(rt); | ||
1766 | + kfree(rt); | ||
1767 | chip->pcm = NULL; | ||
1768 | } | ||
1769 | diff --git a/sound/usb/6fire/pcm.h b/sound/usb/6fire/pcm.h | ||
1770 | index 9b01133..f5779d6 100644 | ||
1771 | --- a/sound/usb/6fire/pcm.h | ||
1772 | +++ b/sound/usb/6fire/pcm.h | ||
1773 | @@ -32,7 +32,7 @@ struct pcm_urb { | ||
1774 | struct urb instance; | ||
1775 | struct usb_iso_packet_descriptor packets[PCM_N_PACKETS_PER_URB]; | ||
1776 | /* END DO NOT SEPARATE */ | ||
1777 | - u8 buffer[PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE]; | ||
1778 | + u8 *buffer; | ||
1779 | |||
1780 | struct pcm_urb *peer; | ||
1781 | }; | ||
1782 | diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c | ||
1783 | index d543808..95558ef 100644 | ||
1784 | --- a/sound/usb/mixer.c | ||
1785 | +++ b/sound/usb/mixer.c | ||
1786 | @@ -888,6 +888,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, | ||
1787 | case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */ | ||
1788 | case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ | ||
1789 | case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */ | ||
1790 | + case USB_ID(0x046d, 0x0826): /* HD Webcam c525 */ | ||
1791 | case USB_ID(0x046d, 0x0991): | ||
1792 | /* Most audio usb devices lie about volume resolution. | ||
1793 | * Most Logitech webcams have res = 384. |