Annotation of /trunk/kernel-alx/patches-3.4/0124-3.4.25-all-fixes.patch
Parent Directory | Revision Log
Revision 2110 -
(hide annotations)
(download)
Tue Mar 12 12:15:23 2013 UTC (11 years, 6 months ago) by niro
File size: 110677 byte(s)
Tue Mar 12 12:15:23 2013 UTC (11 years, 6 months ago) by niro
File size: 110677 byte(s)
-sync with upstream
1 | niro | 2110 | diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt |
2 | index 1619a8c..7977153 100644 | ||
3 | --- a/Documentation/networking/ip-sysctl.txt | ||
4 | +++ b/Documentation/networking/ip-sysctl.txt | ||
5 | @@ -537,6 +537,11 @@ tcp_thin_dupack - BOOLEAN | ||
6 | Documentation/networking/tcp-thin.txt | ||
7 | Default: 0 | ||
8 | |||
9 | +tcp_challenge_ack_limit - INTEGER | ||
10 | + Limits number of Challenge ACK sent per second, as recommended | ||
11 | + in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks) | ||
12 | + Default: 100 | ||
13 | + | ||
14 | UDP variables: | ||
15 | |||
16 | udp_mem - vector of 3 INTEGERs: min, pressure, max | ||
17 | diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c | ||
18 | index df74518..ab1017b 100644 | ||
19 | --- a/arch/arm/kernel/swp_emulate.c | ||
20 | +++ b/arch/arm/kernel/swp_emulate.c | ||
21 | @@ -109,10 +109,12 @@ static void set_segfault(struct pt_regs *regs, unsigned long addr) | ||
22 | { | ||
23 | siginfo_t info; | ||
24 | |||
25 | + down_read(¤t->mm->mmap_sem); | ||
26 | if (find_vma(current->mm, addr) == NULL) | ||
27 | info.si_code = SEGV_MAPERR; | ||
28 | else | ||
29 | info.si_code = SEGV_ACCERR; | ||
30 | + up_read(¤t->mm->mmap_sem); | ||
31 | |||
32 | info.si_signo = SIGSEGV; | ||
33 | info.si_errno = 0; | ||
34 | diff --git a/arch/arm/mach-realview/include/mach/board-eb.h b/arch/arm/mach-realview/include/mach/board-eb.h | ||
35 | index 124bce6..a301e61 100644 | ||
36 | --- a/arch/arm/mach-realview/include/mach/board-eb.h | ||
37 | +++ b/arch/arm/mach-realview/include/mach/board-eb.h | ||
38 | @@ -47,7 +47,7 @@ | ||
39 | #define REALVIEW_EB_USB_BASE 0x4F000000 /* USB */ | ||
40 | |||
41 | #ifdef CONFIG_REALVIEW_EB_ARM11MP_REVB | ||
42 | -#define REALVIEW_EB11MP_PRIV_MEM_BASE 0x1F000000 | ||
43 | +#define REALVIEW_EB11MP_PRIV_MEM_BASE 0x10100000 | ||
44 | #define REALVIEW_EB11MP_L220_BASE 0x10102000 /* L220 registers */ | ||
45 | #define REALVIEW_EB11MP_SYS_PLD_CTRL1 0xD8 /* Register offset for MPCore sysctl */ | ||
46 | #else | ||
47 | diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c | ||
48 | index 7d41919..5df5492 100644 | ||
49 | --- a/arch/arm/mm/mmu.c | ||
50 | +++ b/arch/arm/mm/mmu.c | ||
51 | @@ -497,7 +497,7 @@ static void __init build_mem_type_table(void) | ||
52 | #endif | ||
53 | |||
54 | for (i = 0; i < 16; i++) { | ||
55 | - unsigned long v = pgprot_val(protection_map[i]); | ||
56 | + pteval_t v = pgprot_val(protection_map[i]); | ||
57 | protection_map[i] = __pgprot(v | user_pgprot); | ||
58 | } | ||
59 | |||
60 | diff --git a/arch/cris/include/asm/io.h b/arch/cris/include/asm/io.h | ||
61 | index 32567bc..ac12ae2 100644 | ||
62 | --- a/arch/cris/include/asm/io.h | ||
63 | +++ b/arch/cris/include/asm/io.h | ||
64 | @@ -133,12 +133,39 @@ static inline void writel(unsigned int b, volatile void __iomem *addr) | ||
65 | #define insb(port,addr,count) (cris_iops ? cris_iops->read_io(port,addr,1,count) : 0) | ||
66 | #define insw(port,addr,count) (cris_iops ? cris_iops->read_io(port,addr,2,count) : 0) | ||
67 | #define insl(port,addr,count) (cris_iops ? cris_iops->read_io(port,addr,4,count) : 0) | ||
68 | -#define outb(data,port) if (cris_iops) cris_iops->write_io(port,(void*)(unsigned)data,1,1) | ||
69 | -#define outw(data,port) if (cris_iops) cris_iops->write_io(port,(void*)(unsigned)data,2,1) | ||
70 | -#define outl(data,port) if (cris_iops) cris_iops->write_io(port,(void*)(unsigned)data,4,1) | ||
71 | -#define outsb(port,addr,count) if(cris_iops) cris_iops->write_io(port,(void*)addr,1,count) | ||
72 | -#define outsw(port,addr,count) if(cris_iops) cris_iops->write_io(port,(void*)addr,2,count) | ||
73 | -#define outsl(port,addr,count) if(cris_iops) cris_iops->write_io(port,(void*)addr,3,count) | ||
74 | +static inline void outb(unsigned char data, unsigned int port) | ||
75 | +{ | ||
76 | + if (cris_iops) | ||
77 | + cris_iops->write_io(port, (void *) &data, 1, 1); | ||
78 | +} | ||
79 | +static inline void outw(unsigned short data, unsigned int port) | ||
80 | +{ | ||
81 | + if (cris_iops) | ||
82 | + cris_iops->write_io(port, (void *) &data, 2, 1); | ||
83 | +} | ||
84 | +static inline void outl(unsigned int data, unsigned int port) | ||
85 | +{ | ||
86 | + if (cris_iops) | ||
87 | + cris_iops->write_io(port, (void *) &data, 4, 1); | ||
88 | +} | ||
89 | +static inline void outsb(unsigned int port, const void *addr, | ||
90 | + unsigned long count) | ||
91 | +{ | ||
92 | + if (cris_iops) | ||
93 | + cris_iops->write_io(port, (void *)addr, 1, count); | ||
94 | +} | ||
95 | +static inline void outsw(unsigned int port, const void *addr, | ||
96 | + unsigned long count) | ||
97 | +{ | ||
98 | + if (cris_iops) | ||
99 | + cris_iops->write_io(port, (void *)addr, 2, count); | ||
100 | +} | ||
101 | +static inline void outsl(unsigned int port, const void *addr, | ||
102 | + unsigned long count) | ||
103 | +{ | ||
104 | + if (cris_iops) | ||
105 | + cris_iops->write_io(port, (void *)addr, 4, count); | ||
106 | +} | ||
107 | |||
108 | /* | ||
109 | * Convert a physical pointer to a virtual kernel pointer for /dev/mem | ||
110 | diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h | ||
111 | index 1770610..f368cef 100644 | ||
112 | --- a/arch/sparc/include/asm/hugetlb.h | ||
113 | +++ b/arch/sparc/include/asm/hugetlb.h | ||
114 | @@ -58,14 +58,20 @@ static inline pte_t huge_pte_wrprotect(pte_t pte) | ||
115 | static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, | ||
116 | unsigned long addr, pte_t *ptep) | ||
117 | { | ||
118 | - ptep_set_wrprotect(mm, addr, ptep); | ||
119 | + pte_t old_pte = *ptep; | ||
120 | + set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); | ||
121 | } | ||
122 | |||
123 | static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, | ||
124 | unsigned long addr, pte_t *ptep, | ||
125 | pte_t pte, int dirty) | ||
126 | { | ||
127 | - return ptep_set_access_flags(vma, addr, ptep, pte, dirty); | ||
128 | + int changed = !pte_same(*ptep, pte); | ||
129 | + if (changed) { | ||
130 | + set_huge_pte_at(vma->vm_mm, addr, ptep, pte); | ||
131 | + flush_tlb_page(vma, addr); | ||
132 | + } | ||
133 | + return changed; | ||
134 | } | ||
135 | |||
136 | static inline pte_t huge_ptep_get(pte_t *ptep) | ||
137 | diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c | ||
138 | index 146bb62..6b4976b 100644 | ||
139 | --- a/arch/x86/kernel/cpu/amd.c | ||
140 | +++ b/arch/x86/kernel/cpu/amd.c | ||
141 | @@ -598,6 +598,20 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | ||
142 | } | ||
143 | } | ||
144 | |||
145 | + /* | ||
146 | + * The way access filter has a performance penalty on some workloads. | ||
147 | + * Disable it on the affected CPUs. | ||
148 | + */ | ||
149 | + if ((c->x86 == 0x15) && | ||
150 | + (c->x86_model >= 0x02) && (c->x86_model < 0x20)) { | ||
151 | + u64 val; | ||
152 | + | ||
153 | + if (!rdmsrl_safe(0xc0011021, &val) && !(val & 0x1E)) { | ||
154 | + val |= 0x1E; | ||
155 | + checking_wrmsrl(0xc0011021, val); | ||
156 | + } | ||
157 | + } | ||
158 | + | ||
159 | cpu_detect_cache_sizes(c); | ||
160 | |||
161 | /* Multi core CPU? */ | ||
162 | diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c | ||
163 | index 85cbfdc..bd3199c 100644 | ||
164 | --- a/drivers/acpi/scan.c | ||
165 | +++ b/drivers/acpi/scan.c | ||
166 | @@ -1157,7 +1157,7 @@ static void acpi_device_set_id(struct acpi_device *device) | ||
167 | acpi_add_id(device, ACPI_DOCK_HID); | ||
168 | else if (!acpi_ibm_smbus_match(device)) | ||
169 | acpi_add_id(device, ACPI_SMBUS_IBM_HID); | ||
170 | - else if (!acpi_device_hid(device) && | ||
171 | + else if (list_empty(&device->pnp.ids) && | ||
172 | ACPI_IS_ROOT_DEVICE(device->parent)) { | ||
173 | acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */ | ||
174 | strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME); | ||
175 | diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c | ||
176 | index 480b648..aa0a904 100644 | ||
177 | --- a/drivers/acpi/sleep.c | ||
178 | +++ b/drivers/acpi/sleep.c | ||
179 | @@ -138,6 +138,180 @@ void __init acpi_old_suspend_ordering(void) | ||
180 | old_suspend_ordering = true; | ||
181 | } | ||
182 | |||
183 | +static int __init init_old_suspend_ordering(const struct dmi_system_id *d) | ||
184 | +{ | ||
185 | + acpi_old_suspend_ordering(); | ||
186 | + return 0; | ||
187 | +} | ||
188 | + | ||
189 | +static int __init init_nvs_nosave(const struct dmi_system_id *d) | ||
190 | +{ | ||
191 | + acpi_nvs_nosave(); | ||
192 | + return 0; | ||
193 | +} | ||
194 | + | ||
195 | +static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | ||
196 | + { | ||
197 | + .callback = init_old_suspend_ordering, | ||
198 | + .ident = "Abit KN9 (nForce4 variant)", | ||
199 | + .matches = { | ||
200 | + DMI_MATCH(DMI_BOARD_VENDOR, "http://www.abit.com.tw/"), | ||
201 | + DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"), | ||
202 | + }, | ||
203 | + }, | ||
204 | + { | ||
205 | + .callback = init_old_suspend_ordering, | ||
206 | + .ident = "HP xw4600 Workstation", | ||
207 | + .matches = { | ||
208 | + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
209 | + DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"), | ||
210 | + }, | ||
211 | + }, | ||
212 | + { | ||
213 | + .callback = init_old_suspend_ordering, | ||
214 | + .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)", | ||
215 | + .matches = { | ||
216 | + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek Computer INC."), | ||
217 | + DMI_MATCH(DMI_BOARD_NAME, "M2N8L"), | ||
218 | + }, | ||
219 | + }, | ||
220 | + { | ||
221 | + .callback = init_old_suspend_ordering, | ||
222 | + .ident = "Panasonic CF51-2L", | ||
223 | + .matches = { | ||
224 | + DMI_MATCH(DMI_BOARD_VENDOR, | ||
225 | + "Matsushita Electric Industrial Co.,Ltd."), | ||
226 | + DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"), | ||
227 | + }, | ||
228 | + }, | ||
229 | + { | ||
230 | + .callback = init_nvs_nosave, | ||
231 | + .ident = "Sony Vaio VGN-FW21E", | ||
232 | + .matches = { | ||
233 | + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
234 | + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW21E"), | ||
235 | + }, | ||
236 | + }, | ||
237 | + { | ||
238 | + .callback = init_nvs_nosave, | ||
239 | + .ident = "Sony Vaio VPCEB17FX", | ||
240 | + .matches = { | ||
241 | + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
242 | + DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB17FX"), | ||
243 | + }, | ||
244 | + }, | ||
245 | + { | ||
246 | + .callback = init_nvs_nosave, | ||
247 | + .ident = "Sony Vaio VGN-SR11M", | ||
248 | + .matches = { | ||
249 | + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
250 | + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR11M"), | ||
251 | + }, | ||
252 | + }, | ||
253 | + { | ||
254 | + .callback = init_nvs_nosave, | ||
255 | + .ident = "Everex StepNote Series", | ||
256 | + .matches = { | ||
257 | + DMI_MATCH(DMI_SYS_VENDOR, "Everex Systems, Inc."), | ||
258 | + DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"), | ||
259 | + }, | ||
260 | + }, | ||
261 | + { | ||
262 | + .callback = init_nvs_nosave, | ||
263 | + .ident = "Sony Vaio VPCEB1Z1E", | ||
264 | + .matches = { | ||
265 | + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
266 | + DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"), | ||
267 | + }, | ||
268 | + }, | ||
269 | + { | ||
270 | + .callback = init_nvs_nosave, | ||
271 | + .ident = "Sony Vaio VGN-NW130D", | ||
272 | + .matches = { | ||
273 | + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
274 | + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"), | ||
275 | + }, | ||
276 | + }, | ||
277 | + { | ||
278 | + .callback = init_nvs_nosave, | ||
279 | + .ident = "Sony Vaio VPCCW29FX", | ||
280 | + .matches = { | ||
281 | + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
282 | + DMI_MATCH(DMI_PRODUCT_NAME, "VPCCW29FX"), | ||
283 | + }, | ||
284 | + }, | ||
285 | + { | ||
286 | + .callback = init_nvs_nosave, | ||
287 | + .ident = "Averatec AV1020-ED2", | ||
288 | + .matches = { | ||
289 | + DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"), | ||
290 | + DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"), | ||
291 | + }, | ||
292 | + }, | ||
293 | + { | ||
294 | + .callback = init_old_suspend_ordering, | ||
295 | + .ident = "Asus A8N-SLI DELUXE", | ||
296 | + .matches = { | ||
297 | + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | ||
298 | + DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI DELUXE"), | ||
299 | + }, | ||
300 | + }, | ||
301 | + { | ||
302 | + .callback = init_old_suspend_ordering, | ||
303 | + .ident = "Asus A8N-SLI Premium", | ||
304 | + .matches = { | ||
305 | + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | ||
306 | + DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI Premium"), | ||
307 | + }, | ||
308 | + }, | ||
309 | + { | ||
310 | + .callback = init_nvs_nosave, | ||
311 | + .ident = "Sony Vaio VGN-SR26GN_P", | ||
312 | + .matches = { | ||
313 | + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
314 | + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR26GN_P"), | ||
315 | + }, | ||
316 | + }, | ||
317 | + { | ||
318 | + .callback = init_nvs_nosave, | ||
319 | + .ident = "Sony Vaio VPCEB1S1E", | ||
320 | + .matches = { | ||
321 | + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
322 | + DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1S1E"), | ||
323 | + }, | ||
324 | + }, | ||
325 | + { | ||
326 | + .callback = init_nvs_nosave, | ||
327 | + .ident = "Sony Vaio VGN-FW520F", | ||
328 | + .matches = { | ||
329 | + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
330 | + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW520F"), | ||
331 | + }, | ||
332 | + }, | ||
333 | + { | ||
334 | + .callback = init_nvs_nosave, | ||
335 | + .ident = "Asus K54C", | ||
336 | + .matches = { | ||
337 | + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
338 | + DMI_MATCH(DMI_PRODUCT_NAME, "K54C"), | ||
339 | + }, | ||
340 | + }, | ||
341 | + { | ||
342 | + .callback = init_nvs_nosave, | ||
343 | + .ident = "Asus K54HR", | ||
344 | + .matches = { | ||
345 | + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
346 | + DMI_MATCH(DMI_PRODUCT_NAME, "K54HR"), | ||
347 | + }, | ||
348 | + }, | ||
349 | + {}, | ||
350 | +}; | ||
351 | + | ||
352 | +static void acpi_sleep_dmi_check(void) | ||
353 | +{ | ||
354 | + dmi_check_system(acpisleep_dmi_table); | ||
355 | +} | ||
356 | + | ||
357 | /** | ||
358 | * acpi_pm_freeze - Disable the GPEs and suspend EC transactions. | ||
359 | */ | ||
360 | @@ -227,6 +401,7 @@ static void acpi_pm_end(void) | ||
361 | } | ||
362 | #else /* !CONFIG_ACPI_SLEEP */ | ||
363 | #define acpi_target_sleep_state ACPI_STATE_S0 | ||
364 | +static inline void acpi_sleep_dmi_check(void) {} | ||
365 | #endif /* CONFIG_ACPI_SLEEP */ | ||
366 | |||
367 | #ifdef CONFIG_SUSPEND | ||
368 | @@ -371,175 +546,6 @@ static const struct platform_suspend_ops acpi_suspend_ops_old = { | ||
369 | .end = acpi_pm_end, | ||
370 | .recover = acpi_pm_finish, | ||
371 | }; | ||
372 | - | ||
373 | -static int __init init_old_suspend_ordering(const struct dmi_system_id *d) | ||
374 | -{ | ||
375 | - old_suspend_ordering = true; | ||
376 | - return 0; | ||
377 | -} | ||
378 | - | ||
379 | -static int __init init_nvs_nosave(const struct dmi_system_id *d) | ||
380 | -{ | ||
381 | - acpi_nvs_nosave(); | ||
382 | - return 0; | ||
383 | -} | ||
384 | - | ||
385 | -static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | ||
386 | - { | ||
387 | - .callback = init_old_suspend_ordering, | ||
388 | - .ident = "Abit KN9 (nForce4 variant)", | ||
389 | - .matches = { | ||
390 | - DMI_MATCH(DMI_BOARD_VENDOR, "http://www.abit.com.tw/"), | ||
391 | - DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"), | ||
392 | - }, | ||
393 | - }, | ||
394 | - { | ||
395 | - .callback = init_old_suspend_ordering, | ||
396 | - .ident = "HP xw4600 Workstation", | ||
397 | - .matches = { | ||
398 | - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
399 | - DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"), | ||
400 | - }, | ||
401 | - }, | ||
402 | - { | ||
403 | - .callback = init_old_suspend_ordering, | ||
404 | - .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)", | ||
405 | - .matches = { | ||
406 | - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek Computer INC."), | ||
407 | - DMI_MATCH(DMI_BOARD_NAME, "M2N8L"), | ||
408 | - }, | ||
409 | - }, | ||
410 | - { | ||
411 | - .callback = init_old_suspend_ordering, | ||
412 | - .ident = "Panasonic CF51-2L", | ||
413 | - .matches = { | ||
414 | - DMI_MATCH(DMI_BOARD_VENDOR, | ||
415 | - "Matsushita Electric Industrial Co.,Ltd."), | ||
416 | - DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"), | ||
417 | - }, | ||
418 | - }, | ||
419 | - { | ||
420 | - .callback = init_nvs_nosave, | ||
421 | - .ident = "Sony Vaio VGN-FW21E", | ||
422 | - .matches = { | ||
423 | - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
424 | - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW21E"), | ||
425 | - }, | ||
426 | - }, | ||
427 | - { | ||
428 | - .callback = init_nvs_nosave, | ||
429 | - .ident = "Sony Vaio VPCEB17FX", | ||
430 | - .matches = { | ||
431 | - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
432 | - DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB17FX"), | ||
433 | - }, | ||
434 | - }, | ||
435 | - { | ||
436 | - .callback = init_nvs_nosave, | ||
437 | - .ident = "Sony Vaio VGN-SR11M", | ||
438 | - .matches = { | ||
439 | - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
440 | - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR11M"), | ||
441 | - }, | ||
442 | - }, | ||
443 | - { | ||
444 | - .callback = init_nvs_nosave, | ||
445 | - .ident = "Everex StepNote Series", | ||
446 | - .matches = { | ||
447 | - DMI_MATCH(DMI_SYS_VENDOR, "Everex Systems, Inc."), | ||
448 | - DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"), | ||
449 | - }, | ||
450 | - }, | ||
451 | - { | ||
452 | - .callback = init_nvs_nosave, | ||
453 | - .ident = "Sony Vaio VPCEB1Z1E", | ||
454 | - .matches = { | ||
455 | - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
456 | - DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"), | ||
457 | - }, | ||
458 | - }, | ||
459 | - { | ||
460 | - .callback = init_nvs_nosave, | ||
461 | - .ident = "Sony Vaio VGN-NW130D", | ||
462 | - .matches = { | ||
463 | - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
464 | - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"), | ||
465 | - }, | ||
466 | - }, | ||
467 | - { | ||
468 | - .callback = init_nvs_nosave, | ||
469 | - .ident = "Sony Vaio VPCCW29FX", | ||
470 | - .matches = { | ||
471 | - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
472 | - DMI_MATCH(DMI_PRODUCT_NAME, "VPCCW29FX"), | ||
473 | - }, | ||
474 | - }, | ||
475 | - { | ||
476 | - .callback = init_nvs_nosave, | ||
477 | - .ident = "Averatec AV1020-ED2", | ||
478 | - .matches = { | ||
479 | - DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"), | ||
480 | - DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"), | ||
481 | - }, | ||
482 | - }, | ||
483 | - { | ||
484 | - .callback = init_old_suspend_ordering, | ||
485 | - .ident = "Asus A8N-SLI DELUXE", | ||
486 | - .matches = { | ||
487 | - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | ||
488 | - DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI DELUXE"), | ||
489 | - }, | ||
490 | - }, | ||
491 | - { | ||
492 | - .callback = init_old_suspend_ordering, | ||
493 | - .ident = "Asus A8N-SLI Premium", | ||
494 | - .matches = { | ||
495 | - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | ||
496 | - DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI Premium"), | ||
497 | - }, | ||
498 | - }, | ||
499 | - { | ||
500 | - .callback = init_nvs_nosave, | ||
501 | - .ident = "Sony Vaio VGN-SR26GN_P", | ||
502 | - .matches = { | ||
503 | - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
504 | - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR26GN_P"), | ||
505 | - }, | ||
506 | - }, | ||
507 | - { | ||
508 | - .callback = init_nvs_nosave, | ||
509 | - .ident = "Sony Vaio VPCEB1S1E", | ||
510 | - .matches = { | ||
511 | - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
512 | - DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1S1E"), | ||
513 | - }, | ||
514 | - }, | ||
515 | - { | ||
516 | - .callback = init_nvs_nosave, | ||
517 | - .ident = "Sony Vaio VGN-FW520F", | ||
518 | - .matches = { | ||
519 | - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
520 | - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW520F"), | ||
521 | - }, | ||
522 | - }, | ||
523 | - { | ||
524 | - .callback = init_nvs_nosave, | ||
525 | - .ident = "Asus K54C", | ||
526 | - .matches = { | ||
527 | - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
528 | - DMI_MATCH(DMI_PRODUCT_NAME, "K54C"), | ||
529 | - }, | ||
530 | - }, | ||
531 | - { | ||
532 | - .callback = init_nvs_nosave, | ||
533 | - .ident = "Asus K54HR", | ||
534 | - .matches = { | ||
535 | - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
536 | - DMI_MATCH(DMI_PRODUCT_NAME, "K54HR"), | ||
537 | - }, | ||
538 | - }, | ||
539 | - {}, | ||
540 | -}; | ||
541 | #endif /* CONFIG_SUSPEND */ | ||
542 | |||
543 | #ifdef CONFIG_HIBERNATION | ||
544 | @@ -880,13 +886,13 @@ int __init acpi_sleep_init(void) | ||
545 | u8 type_a, type_b; | ||
546 | #ifdef CONFIG_SUSPEND | ||
547 | int i = 0; | ||
548 | - | ||
549 | - dmi_check_system(acpisleep_dmi_table); | ||
550 | #endif | ||
551 | |||
552 | if (acpi_disabled) | ||
553 | return 0; | ||
554 | |||
555 | + acpi_sleep_dmi_check(); | ||
556 | + | ||
557 | sleep_states[ACPI_STATE_S0] = 1; | ||
558 | printk(KERN_INFO PREFIX "(supports S0"); | ||
559 | |||
560 | diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c | ||
561 | index 9851093..1853a45 100644 | ||
562 | --- a/drivers/atm/solos-pci.c | ||
563 | +++ b/drivers/atm/solos-pci.c | ||
564 | @@ -967,10 +967,11 @@ static uint32_t fpga_tx(struct solos_card *card) | ||
565 | for (port = 0; tx_pending; tx_pending >>= 1, port++) { | ||
566 | if (tx_pending & 1) { | ||
567 | struct sk_buff *oldskb = card->tx_skb[port]; | ||
568 | - if (oldskb) | ||
569 | + if (oldskb) { | ||
570 | pci_unmap_single(card->dev, SKB_CB(oldskb)->dma_addr, | ||
571 | oldskb->len, PCI_DMA_TODEVICE); | ||
572 | - | ||
573 | + card->tx_skb[port] = NULL; | ||
574 | + } | ||
575 | spin_lock(&card->tx_queue_lock); | ||
576 | skb = skb_dequeue(&card->tx_queue[port]); | ||
577 | if (!skb) | ||
578 | diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c | ||
579 | index 57fd867..1ae7039 100644 | ||
580 | --- a/drivers/bluetooth/ath3k.c | ||
581 | +++ b/drivers/bluetooth/ath3k.c | ||
582 | @@ -66,6 +66,7 @@ static struct usb_device_id ath3k_table[] = { | ||
583 | { USB_DEVICE(0x13d3, 0x3304) }, | ||
584 | { USB_DEVICE(0x0930, 0x0215) }, | ||
585 | { USB_DEVICE(0x0489, 0xE03D) }, | ||
586 | + { USB_DEVICE(0x0489, 0xE027) }, | ||
587 | |||
588 | /* Atheros AR9285 Malbec with sflash firmware */ | ||
589 | { USB_DEVICE(0x03F0, 0x311D) }, | ||
590 | diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c | ||
591 | index 29d31ff..27f9d9f 100644 | ||
592 | --- a/drivers/bluetooth/btusb.c | ||
593 | +++ b/drivers/bluetooth/btusb.c | ||
594 | @@ -130,6 +130,7 @@ static struct usb_device_id blacklist_table[] = { | ||
595 | { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, | ||
596 | { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, | ||
597 | { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, | ||
598 | + { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE }, | ||
599 | |||
600 | /* Atheros AR9285 Malbec with sflash firmware */ | ||
601 | { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, | ||
602 | diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c | ||
603 | index 41d4437..1a92a27 100644 | ||
604 | --- a/drivers/hid/hid-core.c | ||
605 | +++ b/drivers/hid/hid-core.c | ||
606 | @@ -1385,6 +1385,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | ||
607 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, | ||
608 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, | ||
609 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, | ||
610 | + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI) }, | ||
611 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) }, | ||
612 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | ||
613 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | ||
614 | diff --git a/drivers/input/joystick/walkera0701.c b/drivers/input/joystick/walkera0701.c | ||
615 | index 4dfa1ee..f8f892b 100644 | ||
616 | --- a/drivers/input/joystick/walkera0701.c | ||
617 | +++ b/drivers/input/joystick/walkera0701.c | ||
618 | @@ -196,6 +196,7 @@ static void walkera0701_close(struct input_dev *dev) | ||
619 | struct walkera_dev *w = input_get_drvdata(dev); | ||
620 | |||
621 | parport_disable_irq(w->parport); | ||
622 | + hrtimer_cancel(&w->timer); | ||
623 | } | ||
624 | |||
625 | static int walkera0701_connect(struct walkera_dev *w, int parport) | ||
626 | @@ -224,6 +225,9 @@ static int walkera0701_connect(struct walkera_dev *w, int parport) | ||
627 | if (parport_claim(w->pardevice)) | ||
628 | goto init_err1; | ||
629 | |||
630 | + hrtimer_init(&w->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
631 | + w->timer.function = timer_handler; | ||
632 | + | ||
633 | w->input_dev = input_allocate_device(); | ||
634 | if (!w->input_dev) | ||
635 | goto init_err2; | ||
636 | @@ -254,8 +258,6 @@ static int walkera0701_connect(struct walkera_dev *w, int parport) | ||
637 | if (err) | ||
638 | goto init_err3; | ||
639 | |||
640 | - hrtimer_init(&w->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
641 | - w->timer.function = timer_handler; | ||
642 | return 0; | ||
643 | |||
644 | init_err3: | ||
645 | @@ -271,7 +273,6 @@ static int walkera0701_connect(struct walkera_dev *w, int parport) | ||
646 | |||
647 | static void walkera0701_disconnect(struct walkera_dev *w) | ||
648 | { | ||
649 | - hrtimer_cancel(&w->timer); | ||
650 | input_unregister_device(w->input_dev); | ||
651 | parport_release(w->pardevice); | ||
652 | parport_unregister_device(w->pardevice); | ||
653 | diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c | ||
654 | index 661a0ca..1257ce8 100644 | ||
655 | --- a/drivers/input/mouse/sentelic.c | ||
656 | +++ b/drivers/input/mouse/sentelic.c | ||
657 | @@ -759,7 +759,7 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) | ||
658 | fsp_set_slot(dev, 0, fgrs > 0, abs_x, abs_y); | ||
659 | fsp_set_slot(dev, 1, false, 0, 0); | ||
660 | } | ||
661 | - if (fgrs > 0) { | ||
662 | + if (fgrs == 1 || (fgrs == 2 && !(packet[0] & FSP_PB0_MFMC_FGR2))) { | ||
663 | input_report_abs(dev, ABS_X, abs_x); | ||
664 | input_report_abs(dev, ABS_Y, abs_y); | ||
665 | } | ||
666 | diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h | ||
667 | index d6cc77a..5f306f7 100644 | ||
668 | --- a/drivers/input/serio/i8042-x86ia64io.h | ||
669 | +++ b/drivers/input/serio/i8042-x86ia64io.h | ||
670 | @@ -921,6 +921,7 @@ static int __init i8042_platform_init(void) | ||
671 | int retval; | ||
672 | |||
673 | #ifdef CONFIG_X86 | ||
674 | + u8 a20_on = 0xdf; | ||
675 | /* Just return if pre-detection shows no i8042 controller exist */ | ||
676 | if (!x86_platform.i8042_detect()) | ||
677 | return -ENODEV; | ||
678 | @@ -960,6 +961,14 @@ static int __init i8042_platform_init(void) | ||
679 | |||
680 | if (dmi_check_system(i8042_dmi_dritek_table)) | ||
681 | i8042_dritek = true; | ||
682 | + | ||
683 | + /* | ||
684 | + * A20 was already enabled during early kernel init. But some buggy | ||
685 | + * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to | ||
686 | + * resume from S3. So we do it here and hope that nothing breaks. | ||
687 | + */ | ||
688 | + i8042_command(&a20_on, 0x10d1); | ||
689 | + i8042_command(NULL, 0x00ff); /* Null command for SMM firmware */ | ||
690 | #endif /* CONFIG_X86 */ | ||
691 | |||
692 | return retval; | ||
693 | diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c | ||
694 | index 8d082b4..d971817 100644 | ||
695 | --- a/drivers/misc/sgi-xp/xpc_main.c | ||
696 | +++ b/drivers/misc/sgi-xp/xpc_main.c | ||
697 | @@ -53,6 +53,10 @@ | ||
698 | #include <linux/kthread.h> | ||
699 | #include "xpc.h" | ||
700 | |||
701 | +#ifdef CONFIG_X86_64 | ||
702 | +#include <asm/traps.h> | ||
703 | +#endif | ||
704 | + | ||
705 | /* define two XPC debug device structures to be used with dev_dbg() et al */ | ||
706 | |||
707 | struct device_driver xpc_dbg_name = { | ||
708 | @@ -1079,6 +1083,9 @@ xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused) | ||
709 | return NOTIFY_DONE; | ||
710 | } | ||
711 | |||
712 | +/* Used to only allow one cpu to complete disconnect */ | ||
713 | +static unsigned int xpc_die_disconnecting; | ||
714 | + | ||
715 | /* | ||
716 | * Notify other partitions to deactivate from us by first disengaging from all | ||
717 | * references to our memory. | ||
718 | @@ -1092,6 +1099,9 @@ xpc_die_deactivate(void) | ||
719 | long keep_waiting; | ||
720 | long wait_to_print; | ||
721 | |||
722 | + if (cmpxchg(&xpc_die_disconnecting, 0, 1)) | ||
723 | + return; | ||
724 | + | ||
725 | /* keep xpc_hb_checker thread from doing anything (just in case) */ | ||
726 | xpc_exiting = 1; | ||
727 | |||
728 | @@ -1159,7 +1169,7 @@ xpc_die_deactivate(void) | ||
729 | * about the lack of a heartbeat. | ||
730 | */ | ||
731 | static int | ||
732 | -xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused) | ||
733 | +xpc_system_die(struct notifier_block *nb, unsigned long event, void *_die_args) | ||
734 | { | ||
735 | #ifdef CONFIG_IA64 /* !!! temporary kludge */ | ||
736 | switch (event) { | ||
737 | @@ -1191,7 +1201,27 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused) | ||
738 | break; | ||
739 | } | ||
740 | #else | ||
741 | - xpc_die_deactivate(); | ||
742 | + struct die_args *die_args = _die_args; | ||
743 | + | ||
744 | + switch (event) { | ||
745 | + case DIE_TRAP: | ||
746 | + if (die_args->trapnr == X86_TRAP_DF) | ||
747 | + xpc_die_deactivate(); | ||
748 | + | ||
749 | + if (((die_args->trapnr == X86_TRAP_MF) || | ||
750 | + (die_args->trapnr == X86_TRAP_XF)) && | ||
751 | + !user_mode_vm(die_args->regs)) | ||
752 | + xpc_die_deactivate(); | ||
753 | + | ||
754 | + break; | ||
755 | + case DIE_INT3: | ||
756 | + case DIE_DEBUG: | ||
757 | + break; | ||
758 | + case DIE_OOPS: | ||
759 | + case DIE_GPF: | ||
760 | + default: | ||
761 | + xpc_die_deactivate(); | ||
762 | + } | ||
763 | #endif | ||
764 | |||
765 | return NOTIFY_DONE; | ||
766 | diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c | ||
767 | index 318a62a..6df52c9 100644 | ||
768 | --- a/drivers/net/bonding/bond_main.c | ||
769 | +++ b/drivers/net/bonding/bond_main.c | ||
770 | @@ -1383,6 +1383,8 @@ static void bond_compute_features(struct bonding *bond) | ||
771 | struct net_device *bond_dev = bond->dev; | ||
772 | netdev_features_t vlan_features = BOND_VLAN_FEATURES; | ||
773 | unsigned short max_hard_header_len = ETH_HLEN; | ||
774 | + unsigned int gso_max_size = GSO_MAX_SIZE; | ||
775 | + u16 gso_max_segs = GSO_MAX_SEGS; | ||
776 | int i; | ||
777 | |||
778 | read_lock(&bond->lock); | ||
779 | @@ -1396,11 +1398,16 @@ static void bond_compute_features(struct bonding *bond) | ||
780 | |||
781 | if (slave->dev->hard_header_len > max_hard_header_len) | ||
782 | max_hard_header_len = slave->dev->hard_header_len; | ||
783 | + | ||
784 | + gso_max_size = min(gso_max_size, slave->dev->gso_max_size); | ||
785 | + gso_max_segs = min(gso_max_segs, slave->dev->gso_max_segs); | ||
786 | } | ||
787 | |||
788 | done: | ||
789 | bond_dev->vlan_features = vlan_features; | ||
790 | bond_dev->hard_header_len = max_hard_header_len; | ||
791 | + bond_dev->gso_max_segs = gso_max_segs; | ||
792 | + netif_set_gso_max_size(bond_dev, gso_max_size); | ||
793 | |||
794 | read_unlock(&bond->lock); | ||
795 | |||
796 | diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c | ||
797 | index aef42f0..6734737 100644 | ||
798 | --- a/drivers/net/bonding/bond_sysfs.c | ||
799 | +++ b/drivers/net/bonding/bond_sysfs.c | ||
800 | @@ -1578,6 +1578,7 @@ static ssize_t bonding_store_slaves_active(struct device *d, | ||
801 | goto out; | ||
802 | } | ||
803 | |||
804 | + read_lock(&bond->lock); | ||
805 | bond_for_each_slave(bond, slave, i) { | ||
806 | if (!bond_is_active_slave(slave)) { | ||
807 | if (new_value) | ||
808 | @@ -1586,6 +1587,7 @@ static ssize_t bonding_store_slaves_active(struct device *d, | ||
809 | slave->inactive = 1; | ||
810 | } | ||
811 | } | ||
812 | + read_unlock(&bond->lock); | ||
813 | out: | ||
814 | return ret; | ||
815 | } | ||
816 | diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c | ||
817 | index c5fe3a3..e86f4c3 100644 | ||
818 | --- a/drivers/net/can/dev.c | ||
819 | +++ b/drivers/net/can/dev.c | ||
820 | @@ -576,8 +576,7 @@ void close_candev(struct net_device *dev) | ||
821 | { | ||
822 | struct can_priv *priv = netdev_priv(dev); | ||
823 | |||
824 | - if (del_timer_sync(&priv->restart_timer)) | ||
825 | - dev_put(dev); | ||
826 | + del_timer_sync(&priv->restart_timer); | ||
827 | can_flush_echo_skb(dev); | ||
828 | } | ||
829 | EXPORT_SYMBOL_GPL(close_candev); | ||
830 | diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c | ||
831 | index d04911d..47618e5 100644 | ||
832 | --- a/drivers/net/ethernet/8390/ne.c | ||
833 | +++ b/drivers/net/ethernet/8390/ne.c | ||
834 | @@ -813,6 +813,7 @@ static int __init ne_drv_probe(struct platform_device *pdev) | ||
835 | dev->irq = irq[this_dev]; | ||
836 | dev->mem_end = bad[this_dev]; | ||
837 | } | ||
838 | + SET_NETDEV_DEV(dev, &pdev->dev); | ||
839 | err = do_ne_probe(dev); | ||
840 | if (err) { | ||
841 | free_netdev(dev); | ||
842 | diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c | ||
843 | index 5039f08..43e9ab4 100644 | ||
844 | --- a/drivers/net/irda/sir_dev.c | ||
845 | +++ b/drivers/net/irda/sir_dev.c | ||
846 | @@ -222,7 +222,7 @@ static void sirdev_config_fsm(struct work_struct *work) | ||
847 | break; | ||
848 | |||
849 | case SIRDEV_STATE_DONGLE_SPEED: | ||
850 | - if (dev->dongle_drv->reset) { | ||
851 | + if (dev->dongle_drv->set_speed) { | ||
852 | ret = dev->dongle_drv->set_speed(dev, fsm->param); | ||
853 | if (ret < 0) { | ||
854 | fsm->result = ret; | ||
855 | diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c | ||
856 | index 5cba415..32e4791 100644 | ||
857 | --- a/drivers/net/usb/ipheth.c | ||
858 | +++ b/drivers/net/usb/ipheth.c | ||
859 | @@ -62,6 +62,7 @@ | ||
860 | #define USB_PRODUCT_IPAD 0x129a | ||
861 | #define USB_PRODUCT_IPHONE_4_VZW 0x129c | ||
862 | #define USB_PRODUCT_IPHONE_4S 0x12a0 | ||
863 | +#define USB_PRODUCT_IPHONE_5 0x12a8 | ||
864 | |||
865 | #define IPHETH_USBINTF_CLASS 255 | ||
866 | #define IPHETH_USBINTF_SUBCLASS 253 | ||
867 | @@ -113,6 +114,10 @@ static struct usb_device_id ipheth_table[] = { | ||
868 | USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4S, | ||
869 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, | ||
870 | IPHETH_USBINTF_PROTO) }, | ||
871 | + { USB_DEVICE_AND_INTERFACE_INFO( | ||
872 | + USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_5, | ||
873 | + IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, | ||
874 | + IPHETH_USBINTF_PROTO) }, | ||
875 | { } | ||
876 | }; | ||
877 | MODULE_DEVICE_TABLE(usb, ipheth_table); | ||
878 | diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c | ||
879 | index b5f1b91..65f831f 100644 | ||
880 | --- a/drivers/net/wireless/b43/dma.c | ||
881 | +++ b/drivers/net/wireless/b43/dma.c | ||
882 | @@ -409,7 +409,10 @@ static inline | ||
883 | struct b43_dmadesc_meta *meta) | ||
884 | { | ||
885 | if (meta->skb) { | ||
886 | - dev_kfree_skb_any(meta->skb); | ||
887 | + if (ring->tx) | ||
888 | + ieee80211_free_txskb(ring->dev->wl->hw, meta->skb); | ||
889 | + else | ||
890 | + dev_kfree_skb_any(meta->skb); | ||
891 | meta->skb = NULL; | ||
892 | } | ||
893 | } | ||
894 | @@ -1454,7 +1457,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb) | ||
895 | if (unlikely(err == -ENOKEY)) { | ||
896 | /* Drop this packet, as we don't have the encryption key | ||
897 | * anymore and must not transmit it unencrypted. */ | ||
898 | - dev_kfree_skb_any(skb); | ||
899 | + ieee80211_free_txskb(dev->wl->hw, skb); | ||
900 | err = 0; | ||
901 | goto out; | ||
902 | } | ||
903 | diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c | ||
904 | index d6ffd43..4e465c5 100644 | ||
905 | --- a/drivers/net/wireless/b43/main.c | ||
906 | +++ b/drivers/net/wireless/b43/main.c | ||
907 | @@ -3393,7 +3393,7 @@ static void b43_tx_work(struct work_struct *work) | ||
908 | break; | ||
909 | } | ||
910 | if (unlikely(err)) | ||
911 | - dev_kfree_skb(skb); /* Drop it */ | ||
912 | + ieee80211_free_txskb(wl->hw, skb); | ||
913 | err = 0; | ||
914 | } | ||
915 | |||
916 | @@ -3414,7 +3414,7 @@ static void b43_op_tx(struct ieee80211_hw *hw, | ||
917 | |||
918 | if (unlikely(skb->len < 2 + 2 + 6)) { | ||
919 | /* Too short, this can't be a valid frame. */ | ||
920 | - dev_kfree_skb_any(skb); | ||
921 | + ieee80211_free_txskb(hw, skb); | ||
922 | return; | ||
923 | } | ||
924 | B43_WARN_ON(skb_shinfo(skb)->nr_frags); | ||
925 | @@ -4210,8 +4210,12 @@ redo: | ||
926 | |||
927 | /* Drain all TX queues. */ | ||
928 | for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++) { | ||
929 | - while (skb_queue_len(&wl->tx_queue[queue_num])) | ||
930 | - dev_kfree_skb(skb_dequeue(&wl->tx_queue[queue_num])); | ||
931 | + while (skb_queue_len(&wl->tx_queue[queue_num])) { | ||
932 | + struct sk_buff *skb; | ||
933 | + | ||
934 | + skb = skb_dequeue(&wl->tx_queue[queue_num]); | ||
935 | + ieee80211_free_txskb(wl->hw, skb); | ||
936 | + } | ||
937 | } | ||
938 | |||
939 | b43_mac_suspend(dev); | ||
940 | diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c | ||
941 | index 3533ab8..a73ff8c 100644 | ||
942 | --- a/drivers/net/wireless/b43/pio.c | ||
943 | +++ b/drivers/net/wireless/b43/pio.c | ||
944 | @@ -196,7 +196,7 @@ static void b43_pio_cancel_tx_packets(struct b43_pio_txqueue *q) | ||
945 | for (i = 0; i < ARRAY_SIZE(q->packets); i++) { | ||
946 | pack = &(q->packets[i]); | ||
947 | if (pack->skb) { | ||
948 | - dev_kfree_skb_any(pack->skb); | ||
949 | + ieee80211_free_txskb(q->dev->wl->hw, pack->skb); | ||
950 | pack->skb = NULL; | ||
951 | } | ||
952 | } | ||
953 | @@ -552,7 +552,7 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb) | ||
954 | if (unlikely(err == -ENOKEY)) { | ||
955 | /* Drop this packet, as we don't have the encryption key | ||
956 | * anymore and must not transmit it unencrypted. */ | ||
957 | - dev_kfree_skb_any(skb); | ||
958 | + ieee80211_free_txskb(dev->wl->hw, skb); | ||
959 | err = 0; | ||
960 | goto out; | ||
961 | } | ||
962 | diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h | ||
963 | index a29da67..482476f 100644 | ||
964 | --- a/drivers/net/wireless/b43legacy/b43legacy.h | ||
965 | +++ b/drivers/net/wireless/b43legacy/b43legacy.h | ||
966 | @@ -13,6 +13,7 @@ | ||
967 | |||
968 | #include <linux/ssb/ssb.h> | ||
969 | #include <linux/ssb/ssb_driver_chipcommon.h> | ||
970 | +#include <linux/completion.h> | ||
971 | |||
972 | #include <net/mac80211.h> | ||
973 | |||
974 | @@ -733,6 +734,10 @@ struct b43legacy_wldev { | ||
975 | |||
976 | /* Firmware data */ | ||
977 | struct b43legacy_firmware fw; | ||
978 | + const struct firmware *fwp; /* needed to pass fw pointer */ | ||
979 | + | ||
980 | + /* completion struct for firmware loading */ | ||
981 | + struct completion fw_load_complete; | ||
982 | |||
983 | /* Devicelist in struct b43legacy_wl (all 802.11 cores) */ | ||
984 | struct list_head list; | ||
985 | diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c | ||
986 | index 0f30c07..53696ef 100644 | ||
987 | --- a/drivers/net/wireless/b43legacy/main.c | ||
988 | +++ b/drivers/net/wireless/b43legacy/main.c | ||
989 | @@ -1511,9 +1511,17 @@ static void b43legacy_print_fw_helptext(struct b43legacy_wl *wl) | ||
990 | "and download the correct firmware (version 3).\n"); | ||
991 | } | ||
992 | |||
993 | +static void b43legacy_fw_cb(const struct firmware *firmware, void *context) | ||
994 | +{ | ||
995 | + struct b43legacy_wldev *dev = context; | ||
996 | + | ||
997 | + dev->fwp = firmware; | ||
998 | + complete(&dev->fw_load_complete); | ||
999 | +} | ||
1000 | + | ||
1001 | static int do_request_fw(struct b43legacy_wldev *dev, | ||
1002 | const char *name, | ||
1003 | - const struct firmware **fw) | ||
1004 | + const struct firmware **fw, bool async) | ||
1005 | { | ||
1006 | char path[sizeof(modparam_fwpostfix) + 32]; | ||
1007 | struct b43legacy_fw_header *hdr; | ||
1008 | @@ -1526,7 +1534,24 @@ static int do_request_fw(struct b43legacy_wldev *dev, | ||
1009 | snprintf(path, ARRAY_SIZE(path), | ||
1010 | "b43legacy%s/%s.fw", | ||
1011 | modparam_fwpostfix, name); | ||
1012 | - err = request_firmware(fw, path, dev->dev->dev); | ||
1013 | + b43legacyinfo(dev->wl, "Loading firmware %s\n", path); | ||
1014 | + if (async) { | ||
1015 | + init_completion(&dev->fw_load_complete); | ||
1016 | + err = request_firmware_nowait(THIS_MODULE, 1, path, | ||
1017 | + dev->dev->dev, GFP_KERNEL, | ||
1018 | + dev, b43legacy_fw_cb); | ||
1019 | + if (err) { | ||
1020 | + b43legacyerr(dev->wl, "Unable to load firmware\n"); | ||
1021 | + return err; | ||
1022 | + } | ||
1023 | + /* stall here until fw ready */ | ||
1024 | + wait_for_completion(&dev->fw_load_complete); | ||
1025 | + if (!dev->fwp) | ||
1026 | + err = -EINVAL; | ||
1027 | + *fw = dev->fwp; | ||
1028 | + } else { | ||
1029 | + err = request_firmware(fw, path, dev->dev->dev); | ||
1030 | + } | ||
1031 | if (err) { | ||
1032 | b43legacyerr(dev->wl, "Firmware file \"%s\" not found " | ||
1033 | "or load failed.\n", path); | ||
1034 | @@ -1578,7 +1603,7 @@ static void b43legacy_request_firmware(struct work_struct *work) | ||
1035 | filename = "ucode4"; | ||
1036 | else | ||
1037 | filename = "ucode5"; | ||
1038 | - err = do_request_fw(dev, filename, &fw->ucode); | ||
1039 | + err = do_request_fw(dev, filename, &fw->ucode, true); | ||
1040 | if (err) | ||
1041 | goto err_load; | ||
1042 | } | ||
1043 | @@ -1587,7 +1612,7 @@ static void b43legacy_request_firmware(struct work_struct *work) | ||
1044 | filename = "pcm4"; | ||
1045 | else | ||
1046 | filename = "pcm5"; | ||
1047 | - err = do_request_fw(dev, filename, &fw->pcm); | ||
1048 | + err = do_request_fw(dev, filename, &fw->pcm, false); | ||
1049 | if (err) | ||
1050 | goto err_load; | ||
1051 | } | ||
1052 | @@ -1605,7 +1630,7 @@ static void b43legacy_request_firmware(struct work_struct *work) | ||
1053 | default: | ||
1054 | goto err_no_initvals; | ||
1055 | } | ||
1056 | - err = do_request_fw(dev, filename, &fw->initvals); | ||
1057 | + err = do_request_fw(dev, filename, &fw->initvals, false); | ||
1058 | if (err) | ||
1059 | goto err_load; | ||
1060 | } | ||
1061 | @@ -1625,7 +1650,7 @@ static void b43legacy_request_firmware(struct work_struct *work) | ||
1062 | default: | ||
1063 | goto err_no_initvals; | ||
1064 | } | ||
1065 | - err = do_request_fw(dev, filename, &fw->initvals_band); | ||
1066 | + err = do_request_fw(dev, filename, &fw->initvals_band, false); | ||
1067 | if (err) | ||
1068 | goto err_load; | ||
1069 | } | ||
1070 | diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c | ||
1071 | index a337a50..be20cf7 100644 | ||
1072 | --- a/drivers/net/wireless/p54/p54usb.c | ||
1073 | +++ b/drivers/net/wireless/p54/p54usb.c | ||
1074 | @@ -47,6 +47,7 @@ static struct usb_device_id p54u_table[] = { | ||
1075 | {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */ | ||
1076 | {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */ | ||
1077 | {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ | ||
1078 | + {USB_DEVICE(0x0675, 0x0530)}, /* DrayTek Vigor 530 */ | ||
1079 | {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */ | ||
1080 | {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */ | ||
1081 | {USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */ | ||
1082 | @@ -82,6 +83,8 @@ static struct usb_device_id p54u_table[] = { | ||
1083 | {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */ | ||
1084 | {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ | ||
1085 | {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ | ||
1086 | + {USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */ | ||
1087 | + {USB_DEVICE(0x083a, 0x4503)}, /* T-Com Sinus 154 data II */ | ||
1088 | {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ | ||
1089 | {USB_DEVICE(0x083a, 0xc501)}, /* Zoom Wireless-G 4410 */ | ||
1090 | {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */ | ||
1091 | @@ -101,6 +104,7 @@ static struct usb_device_id p54u_table[] = { | ||
1092 | {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ | ||
1093 | {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ | ||
1094 | {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ | ||
1095 | + /* {USB_DEVICE(0x15a9, 0x0002)}, * Also SparkLAN WL-682 with 3887 */ | ||
1096 | {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */ | ||
1097 | {USB_DEVICE(0x1740, 0x1000)}, /* Senao NUB-350 */ | ||
1098 | {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ | ||
1099 | diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c | ||
1100 | index aa970fc..8fa144f 100644 | ||
1101 | --- a/drivers/net/wireless/rtlwifi/usb.c | ||
1102 | +++ b/drivers/net/wireless/rtlwifi/usb.c | ||
1103 | @@ -210,17 +210,16 @@ static void _usb_writeN_sync(struct rtl_priv *rtlpriv, u32 addr, void *data, | ||
1104 | u16 index = REALTEK_USB_VENQT_CMD_IDX; | ||
1105 | int pipe = usb_sndctrlpipe(udev, 0); /* write_out */ | ||
1106 | u8 *buffer; | ||
1107 | - dma_addr_t dma_addr; | ||
1108 | |||
1109 | - wvalue = (u16)(addr&0x0000ffff); | ||
1110 | - buffer = usb_alloc_coherent(udev, (size_t)len, GFP_ATOMIC, &dma_addr); | ||
1111 | + wvalue = (u16)(addr & 0x0000ffff); | ||
1112 | + buffer = kmalloc(len, GFP_ATOMIC); | ||
1113 | if (!buffer) | ||
1114 | return; | ||
1115 | memcpy(buffer, data, len); | ||
1116 | usb_control_msg(udev, pipe, request, reqtype, wvalue, | ||
1117 | index, buffer, len, 50); | ||
1118 | |||
1119 | - usb_free_coherent(udev, (size_t)len, buffer, dma_addr); | ||
1120 | + kfree(buffer); | ||
1121 | } | ||
1122 | |||
1123 | static void _rtl_usb_io_handler_init(struct device *dev, | ||
1124 | diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c | ||
1125 | index 4bf7102..680dbfa 100644 | ||
1126 | --- a/drivers/pci/quirks.c | ||
1127 | +++ b/drivers/pci/quirks.c | ||
1128 | @@ -2708,7 +2708,7 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev) | ||
1129 | if (PCI_FUNC(dev->devfn)) | ||
1130 | return; | ||
1131 | /* | ||
1132 | - * RICOH 0xe823 SD/MMC card reader fails to recognize | ||
1133 | + * RICOH 0xe822 and 0xe823 SD/MMC card readers fail to recognize | ||
1134 | * certain types of SD/MMC cards. Lowering the SD base | ||
1135 | * clock frequency from 200Mhz to 50Mhz fixes this issue. | ||
1136 | * | ||
1137 | @@ -2719,7 +2719,8 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev) | ||
1138 | * 0xf9 - Key register for 0x150 | ||
1139 | * 0xfc - key register for 0xe1 | ||
1140 | */ | ||
1141 | - if (dev->device == PCI_DEVICE_ID_RICOH_R5CE823) { | ||
1142 | + if (dev->device == PCI_DEVICE_ID_RICOH_R5CE822 || | ||
1143 | + dev->device == PCI_DEVICE_ID_RICOH_R5CE823) { | ||
1144 | pci_write_config_byte(dev, 0xf9, 0xfc); | ||
1145 | pci_write_config_byte(dev, 0x150, 0x10); | ||
1146 | pci_write_config_byte(dev, 0xf9, 0x00); | ||
1147 | @@ -2746,6 +2747,8 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev) | ||
1148 | } | ||
1149 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); | ||
1150 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); | ||
1151 | +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE822, ricoh_mmc_fixup_r5c832); | ||
1152 | +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE822, ricoh_mmc_fixup_r5c832); | ||
1153 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832); | ||
1154 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832); | ||
1155 | #endif /*CONFIG_MMC_RICOH_MMC*/ | ||
1156 | diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c | ||
1157 | index e353788..291906e 100644 | ||
1158 | --- a/drivers/pnp/pnpacpi/core.c | ||
1159 | +++ b/drivers/pnp/pnpacpi/core.c | ||
1160 | @@ -58,7 +58,7 @@ static inline int __init is_exclusive_device(struct acpi_device *dev) | ||
1161 | if (!(('0' <= (c) && (c) <= '9') || ('A' <= (c) && (c) <= 'F'))) \ | ||
1162 | return 0 | ||
1163 | #define TEST_ALPHA(c) \ | ||
1164 | - if (!('@' <= (c) || (c) <= 'Z')) \ | ||
1165 | + if (!('A' <= (c) && (c) <= 'Z')) \ | ||
1166 | return 0 | ||
1167 | static int __init ispnpidacpi(const char *id) | ||
1168 | { | ||
1169 | diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c | ||
1170 | index 9e94fb1..44878da 100644 | ||
1171 | --- a/drivers/rtc/rtc-vt8500.c | ||
1172 | +++ b/drivers/rtc/rtc-vt8500.c | ||
1173 | @@ -69,7 +69,7 @@ | ||
1174 | | ALARM_SEC_BIT) | ||
1175 | |||
1176 | #define VT8500_RTC_CR_ENABLE (1 << 0) /* Enable RTC */ | ||
1177 | -#define VT8500_RTC_CR_24H (1 << 1) /* 24h time format */ | ||
1178 | +#define VT8500_RTC_CR_12H (1 << 1) /* 12h time format */ | ||
1179 | #define VT8500_RTC_CR_SM_ENABLE (1 << 2) /* Enable periodic irqs */ | ||
1180 | #define VT8500_RTC_CR_SM_SEC (1 << 3) /* 0: 1Hz/60, 1: 1Hz */ | ||
1181 | #define VT8500_RTC_CR_CALIB (1 << 4) /* Enable calibration */ | ||
1182 | @@ -118,7 +118,7 @@ static int vt8500_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
1183 | tm->tm_min = bcd2bin((time & TIME_MIN_MASK) >> TIME_MIN_S); | ||
1184 | tm->tm_hour = bcd2bin((time & TIME_HOUR_MASK) >> TIME_HOUR_S); | ||
1185 | tm->tm_mday = bcd2bin(date & DATE_DAY_MASK); | ||
1186 | - tm->tm_mon = bcd2bin((date & DATE_MONTH_MASK) >> DATE_MONTH_S); | ||
1187 | + tm->tm_mon = bcd2bin((date & DATE_MONTH_MASK) >> DATE_MONTH_S) - 1; | ||
1188 | tm->tm_year = bcd2bin((date & DATE_YEAR_MASK) >> DATE_YEAR_S) | ||
1189 | + ((date >> DATE_CENTURY_S) & 1 ? 200 : 100); | ||
1190 | tm->tm_wday = (time & TIME_DOW_MASK) >> TIME_DOW_S; | ||
1191 | @@ -137,8 +137,9 @@ static int vt8500_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
1192 | } | ||
1193 | |||
1194 | writel((bin2bcd(tm->tm_year - 100) << DATE_YEAR_S) | ||
1195 | - | (bin2bcd(tm->tm_mon) << DATE_MONTH_S) | ||
1196 | - | (bin2bcd(tm->tm_mday)), | ||
1197 | + | (bin2bcd(tm->tm_mon + 1) << DATE_MONTH_S) | ||
1198 | + | (bin2bcd(tm->tm_mday)) | ||
1199 | + | ((tm->tm_year >= 200) << DATE_CENTURY_S), | ||
1200 | vt8500_rtc->regbase + VT8500_RTC_DS); | ||
1201 | writel((bin2bcd(tm->tm_wday) << TIME_DOW_S) | ||
1202 | | (bin2bcd(tm->tm_hour) << TIME_HOUR_S) | ||
1203 | @@ -248,7 +249,7 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev) | ||
1204 | } | ||
1205 | |||
1206 | /* Enable RTC and set it to 24-hour mode */ | ||
1207 | - writel(VT8500_RTC_CR_ENABLE | VT8500_RTC_CR_24H, | ||
1208 | + writel(VT8500_RTC_CR_ENABLE, | ||
1209 | vt8500_rtc->regbase + VT8500_RTC_CR); | ||
1210 | |||
1211 | vt8500_rtc->rtc = rtc_device_register("vt8500-rtc", &pdev->dev, | ||
1212 | diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c | ||
1213 | index 30b908f..672c66a 100644 | ||
1214 | --- a/drivers/usb/gadget/f_ecm.c | ||
1215 | +++ b/drivers/usb/gadget/f_ecm.c | ||
1216 | @@ -808,9 +808,9 @@ fail: | ||
1217 | /* we might as well release our claims on endpoints */ | ||
1218 | if (ecm->notify) | ||
1219 | ecm->notify->driver_data = NULL; | ||
1220 | - if (ecm->port.out_ep->desc) | ||
1221 | + if (ecm->port.out_ep) | ||
1222 | ecm->port.out_ep->driver_data = NULL; | ||
1223 | - if (ecm->port.in_ep->desc) | ||
1224 | + if (ecm->port.in_ep) | ||
1225 | ecm->port.in_ep->driver_data = NULL; | ||
1226 | |||
1227 | ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); | ||
1228 | diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c | ||
1229 | index 1a7b2dd..a9cf2052 100644 | ||
1230 | --- a/drivers/usb/gadget/f_eem.c | ||
1231 | +++ b/drivers/usb/gadget/f_eem.c | ||
1232 | @@ -319,10 +319,9 @@ fail: | ||
1233 | if (f->hs_descriptors) | ||
1234 | usb_free_descriptors(f->hs_descriptors); | ||
1235 | |||
1236 | - /* we might as well release our claims on endpoints */ | ||
1237 | - if (eem->port.out_ep->desc) | ||
1238 | + if (eem->port.out_ep) | ||
1239 | eem->port.out_ep->driver_data = NULL; | ||
1240 | - if (eem->port.in_ep->desc) | ||
1241 | + if (eem->port.in_ep) | ||
1242 | eem->port.in_ep->driver_data = NULL; | ||
1243 | |||
1244 | ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); | ||
1245 | diff --git a/drivers/usb/gadget/f_midi.c b/drivers/usb/gadget/f_midi.c | ||
1246 | index 2f7e8f2..1bf9596 100644 | ||
1247 | --- a/drivers/usb/gadget/f_midi.c | ||
1248 | +++ b/drivers/usb/gadget/f_midi.c | ||
1249 | @@ -416,6 +416,7 @@ static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f) | ||
1250 | midi->id = NULL; | ||
1251 | |||
1252 | usb_free_descriptors(f->descriptors); | ||
1253 | + usb_free_descriptors(f->hs_descriptors); | ||
1254 | kfree(midi); | ||
1255 | } | ||
1256 | |||
1257 | diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c | ||
1258 | index aab8ede..d7811ae 100644 | ||
1259 | --- a/drivers/usb/gadget/f_ncm.c | ||
1260 | +++ b/drivers/usb/gadget/f_ncm.c | ||
1261 | @@ -1259,9 +1259,9 @@ fail: | ||
1262 | /* we might as well release our claims on endpoints */ | ||
1263 | if (ncm->notify) | ||
1264 | ncm->notify->driver_data = NULL; | ||
1265 | - if (ncm->port.out_ep->desc) | ||
1266 | + if (ncm->port.out_ep) | ||
1267 | ncm->port.out_ep->driver_data = NULL; | ||
1268 | - if (ncm->port.in_ep->desc) | ||
1269 | + if (ncm->port.in_ep) | ||
1270 | ncm->port.in_ep->driver_data = NULL; | ||
1271 | |||
1272 | ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); | ||
1273 | diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c | ||
1274 | index 965a629..16512f9 100644 | ||
1275 | --- a/drivers/usb/gadget/f_phonet.c | ||
1276 | +++ b/drivers/usb/gadget/f_phonet.c | ||
1277 | @@ -531,7 +531,7 @@ int pn_bind(struct usb_configuration *c, struct usb_function *f) | ||
1278 | |||
1279 | req = usb_ep_alloc_request(fp->out_ep, GFP_KERNEL); | ||
1280 | if (!req) | ||
1281 | - goto err; | ||
1282 | + goto err_req; | ||
1283 | |||
1284 | req->complete = pn_rx_complete; | ||
1285 | fp->out_reqv[i] = req; | ||
1286 | @@ -540,14 +540,18 @@ int pn_bind(struct usb_configuration *c, struct usb_function *f) | ||
1287 | /* Outgoing USB requests */ | ||
1288 | fp->in_req = usb_ep_alloc_request(fp->in_ep, GFP_KERNEL); | ||
1289 | if (!fp->in_req) | ||
1290 | - goto err; | ||
1291 | + goto err_req; | ||
1292 | |||
1293 | INFO(cdev, "USB CDC Phonet function\n"); | ||
1294 | INFO(cdev, "using %s, OUT %s, IN %s\n", cdev->gadget->name, | ||
1295 | fp->out_ep->name, fp->in_ep->name); | ||
1296 | return 0; | ||
1297 | |||
1298 | +err_req: | ||
1299 | + for (i = 0; i < phonet_rxq_size && fp->out_reqv[i]; i++) | ||
1300 | + usb_ep_free_request(fp->out_ep, fp->out_reqv[i]); | ||
1301 | err: | ||
1302 | + | ||
1303 | if (fp->out_ep) | ||
1304 | fp->out_ep->driver_data = NULL; | ||
1305 | if (fp->in_ep) | ||
1306 | diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c | ||
1307 | index 5234365..345f838 100644 | ||
1308 | --- a/drivers/usb/gadget/f_rndis.c | ||
1309 | +++ b/drivers/usb/gadget/f_rndis.c | ||
1310 | @@ -803,9 +803,9 @@ fail: | ||
1311 | /* we might as well release our claims on endpoints */ | ||
1312 | if (rndis->notify) | ||
1313 | rndis->notify->driver_data = NULL; | ||
1314 | - if (rndis->port.out_ep->desc) | ||
1315 | + if (rndis->port.out_ep) | ||
1316 | rndis->port.out_ep->driver_data = NULL; | ||
1317 | - if (rndis->port.in_ep->desc) | ||
1318 | + if (rndis->port.in_ep) | ||
1319 | rndis->port.in_ep->driver_data = NULL; | ||
1320 | |||
1321 | ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); | ||
1322 | diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c | ||
1323 | index 21ab474..e5bb966 100644 | ||
1324 | --- a/drivers/usb/gadget/f_subset.c | ||
1325 | +++ b/drivers/usb/gadget/f_subset.c | ||
1326 | @@ -370,9 +370,9 @@ fail: | ||
1327 | usb_free_descriptors(f->hs_descriptors); | ||
1328 | |||
1329 | /* we might as well release our claims on endpoints */ | ||
1330 | - if (geth->port.out_ep->desc) | ||
1331 | + if (geth->port.out_ep) | ||
1332 | geth->port.out_ep->driver_data = NULL; | ||
1333 | - if (geth->port.in_ep->desc) | ||
1334 | + if (geth->port.in_ep) | ||
1335 | geth->port.in_ep->driver_data = NULL; | ||
1336 | |||
1337 | ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); | ||
1338 | diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c | ||
1339 | index 2022fe49..a0abc65 100644 | ||
1340 | --- a/drivers/usb/gadget/f_uvc.c | ||
1341 | +++ b/drivers/usb/gadget/f_uvc.c | ||
1342 | @@ -335,7 +335,6 @@ uvc_register_video(struct uvc_device *uvc) | ||
1343 | return -ENOMEM; | ||
1344 | |||
1345 | video->parent = &cdev->gadget->dev; | ||
1346 | - video->minor = -1; | ||
1347 | video->fops = &uvc_v4l2_fops; | ||
1348 | video->release = video_device_release; | ||
1349 | strncpy(video->name, cdev->gadget->name, sizeof(video->name)); | ||
1350 | @@ -462,23 +461,12 @@ uvc_function_unbind(struct usb_configuration *c, struct usb_function *f) | ||
1351 | |||
1352 | INFO(cdev, "uvc_function_unbind\n"); | ||
1353 | |||
1354 | - if (uvc->vdev) { | ||
1355 | - if (uvc->vdev->minor == -1) | ||
1356 | - video_device_release(uvc->vdev); | ||
1357 | - else | ||
1358 | - video_unregister_device(uvc->vdev); | ||
1359 | - uvc->vdev = NULL; | ||
1360 | - } | ||
1361 | - | ||
1362 | - if (uvc->control_ep) | ||
1363 | - uvc->control_ep->driver_data = NULL; | ||
1364 | - if (uvc->video.ep) | ||
1365 | - uvc->video.ep->driver_data = NULL; | ||
1366 | + video_unregister_device(uvc->vdev); | ||
1367 | + uvc->control_ep->driver_data = NULL; | ||
1368 | + uvc->video.ep->driver_data = NULL; | ||
1369 | |||
1370 | - if (uvc->control_req) { | ||
1371 | - usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); | ||
1372 | - kfree(uvc->control_buf); | ||
1373 | - } | ||
1374 | + usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); | ||
1375 | + kfree(uvc->control_buf); | ||
1376 | |||
1377 | kfree(f->descriptors); | ||
1378 | kfree(f->hs_descriptors); | ||
1379 | @@ -563,7 +551,22 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) | ||
1380 | return 0; | ||
1381 | |||
1382 | error: | ||
1383 | - uvc_function_unbind(c, f); | ||
1384 | + if (uvc->vdev) | ||
1385 | + video_device_release(uvc->vdev); | ||
1386 | + | ||
1387 | + if (uvc->control_ep) | ||
1388 | + uvc->control_ep->driver_data = NULL; | ||
1389 | + if (uvc->video.ep) | ||
1390 | + uvc->video.ep->driver_data = NULL; | ||
1391 | + | ||
1392 | + if (uvc->control_req) { | ||
1393 | + usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); | ||
1394 | + kfree(uvc->control_buf); | ||
1395 | + } | ||
1396 | + | ||
1397 | + kfree(f->descriptors); | ||
1398 | + kfree(f->hs_descriptors); | ||
1399 | + kfree(f->ss_descriptors); | ||
1400 | return ret; | ||
1401 | } | ||
1402 | |||
1403 | diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c | ||
1404 | index 1234817..0909783 100644 | ||
1405 | --- a/drivers/usb/host/ehci-pci.c | ||
1406 | +++ b/drivers/usb/host/ehci-pci.c | ||
1407 | @@ -362,7 +362,8 @@ static bool usb_is_intel_switchable_ehci(struct pci_dev *pdev) | ||
1408 | pdev->vendor == PCI_VENDOR_ID_INTEL && | ||
1409 | (pdev->device == 0x1E26 || | ||
1410 | pdev->device == 0x8C2D || | ||
1411 | - pdev->device == 0x8C26); | ||
1412 | + pdev->device == 0x8C26 || | ||
1413 | + pdev->device == 0x9C26); | ||
1414 | } | ||
1415 | |||
1416 | static void ehci_enable_xhci_companion(void) | ||
1417 | diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c | ||
1418 | index 39f9e4a..eb5563a 100644 | ||
1419 | --- a/drivers/usb/host/pci-quirks.c | ||
1420 | +++ b/drivers/usb/host/pci-quirks.c | ||
1421 | @@ -723,6 +723,7 @@ static int handshake(void __iomem *ptr, u32 mask, u32 done, | ||
1422 | } | ||
1423 | |||
1424 | #define PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI 0x8C31 | ||
1425 | +#define PCI_DEVICE_ID_INTEL_LYNX_POINT_LP_XHCI 0x9C31 | ||
1426 | |||
1427 | bool usb_is_intel_ppt_switchable_xhci(struct pci_dev *pdev) | ||
1428 | { | ||
1429 | @@ -736,7 +737,8 @@ bool usb_is_intel_lpt_switchable_xhci(struct pci_dev *pdev) | ||
1430 | { | ||
1431 | return pdev->class == PCI_CLASS_SERIAL_USB_XHCI && | ||
1432 | pdev->vendor == PCI_VENDOR_ID_INTEL && | ||
1433 | - pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI; | ||
1434 | + (pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI || | ||
1435 | + pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_LP_XHCI); | ||
1436 | } | ||
1437 | |||
1438 | bool usb_is_intel_switchable_xhci(struct pci_dev *pdev) | ||
1439 | diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c | ||
1440 | index cbed50a..3e16f1c 100644 | ||
1441 | --- a/drivers/usb/host/xhci-mem.c | ||
1442 | +++ b/drivers/usb/host/xhci-mem.c | ||
1443 | @@ -205,7 +205,12 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci, | ||
1444 | |||
1445 | next = xhci_segment_alloc(xhci, cycle_state, flags); | ||
1446 | if (!next) { | ||
1447 | - xhci_free_segments_for_ring(xhci, *first); | ||
1448 | + prev = *first; | ||
1449 | + while (prev) { | ||
1450 | + next = prev->next; | ||
1451 | + xhci_segment_free(xhci, prev); | ||
1452 | + prev = next; | ||
1453 | + } | ||
1454 | return -ENOMEM; | ||
1455 | } | ||
1456 | xhci_link_segments(xhci, prev, next, type); | ||
1457 | @@ -258,7 +263,7 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, | ||
1458 | return ring; | ||
1459 | |||
1460 | fail: | ||
1461 | - xhci_ring_free(xhci, ring); | ||
1462 | + kfree(ring); | ||
1463 | return NULL; | ||
1464 | } | ||
1465 | |||
1466 | diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c | ||
1467 | index 23aebcb..bf8bcc4 100644 | ||
1468 | --- a/drivers/usb/host/xhci-ring.c | ||
1469 | +++ b/drivers/usb/host/xhci-ring.c | ||
1470 | @@ -3069,11 +3069,11 @@ static u32 xhci_td_remainder(unsigned int remainder) | ||
1471 | } | ||
1472 | |||
1473 | /* | ||
1474 | - * For xHCI 1.0 host controllers, TD size is the number of packets remaining in | ||
1475 | - * the TD (*not* including this TRB). | ||
1476 | + * For xHCI 1.0 host controllers, TD size is the number of max packet sized | ||
1477 | + * packets remaining in the TD (*not* including this TRB). | ||
1478 | * | ||
1479 | * Total TD packet count = total_packet_count = | ||
1480 | - * roundup(TD size in bytes / wMaxPacketSize) | ||
1481 | + * DIV_ROUND_UP(TD size in bytes / wMaxPacketSize) | ||
1482 | * | ||
1483 | * Packets transferred up to and including this TRB = packets_transferred = | ||
1484 | * rounddown(total bytes transferred including this TRB / wMaxPacketSize) | ||
1485 | @@ -3081,15 +3081,16 @@ static u32 xhci_td_remainder(unsigned int remainder) | ||
1486 | * TD size = total_packet_count - packets_transferred | ||
1487 | * | ||
1488 | * It must fit in bits 21:17, so it can't be bigger than 31. | ||
1489 | + * The last TRB in a TD must have the TD size set to zero. | ||
1490 | */ | ||
1491 | - | ||
1492 | static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len, | ||
1493 | - unsigned int total_packet_count, struct urb *urb) | ||
1494 | + unsigned int total_packet_count, struct urb *urb, | ||
1495 | + unsigned int num_trbs_left) | ||
1496 | { | ||
1497 | int packets_transferred; | ||
1498 | |||
1499 | /* One TRB with a zero-length data packet. */ | ||
1500 | - if (running_total == 0 && trb_buff_len == 0) | ||
1501 | + if (num_trbs_left == 0 || (running_total == 0 && trb_buff_len == 0)) | ||
1502 | return 0; | ||
1503 | |||
1504 | /* All the TRB queueing functions don't count the current TRB in | ||
1505 | @@ -3098,7 +3099,9 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len, | ||
1506 | packets_transferred = (running_total + trb_buff_len) / | ||
1507 | usb_endpoint_maxp(&urb->ep->desc); | ||
1508 | |||
1509 | - return xhci_td_remainder(total_packet_count - packets_transferred); | ||
1510 | + if ((total_packet_count - packets_transferred) > 31) | ||
1511 | + return 31 << 17; | ||
1512 | + return (total_packet_count - packets_transferred) << 17; | ||
1513 | } | ||
1514 | |||
1515 | static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | ||
1516 | @@ -3125,7 +3128,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | ||
1517 | |||
1518 | num_trbs = count_sg_trbs_needed(xhci, urb); | ||
1519 | num_sgs = urb->num_mapped_sgs; | ||
1520 | - total_packet_count = roundup(urb->transfer_buffer_length, | ||
1521 | + total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length, | ||
1522 | usb_endpoint_maxp(&urb->ep->desc)); | ||
1523 | |||
1524 | trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id], | ||
1525 | @@ -3208,7 +3211,8 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | ||
1526 | running_total); | ||
1527 | } else { | ||
1528 | remainder = xhci_v1_0_td_remainder(running_total, | ||
1529 | - trb_buff_len, total_packet_count, urb); | ||
1530 | + trb_buff_len, total_packet_count, urb, | ||
1531 | + num_trbs - 1); | ||
1532 | } | ||
1533 | length_field = TRB_LEN(trb_buff_len) | | ||
1534 | remainder | | ||
1535 | @@ -3316,7 +3320,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | ||
1536 | start_cycle = ep_ring->cycle_state; | ||
1537 | |||
1538 | running_total = 0; | ||
1539 | - total_packet_count = roundup(urb->transfer_buffer_length, | ||
1540 | + total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length, | ||
1541 | usb_endpoint_maxp(&urb->ep->desc)); | ||
1542 | /* How much data is in the first TRB? */ | ||
1543 | addr = (u64) urb->transfer_dma; | ||
1544 | @@ -3362,7 +3366,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | ||
1545 | running_total); | ||
1546 | } else { | ||
1547 | remainder = xhci_v1_0_td_remainder(running_total, | ||
1548 | - trb_buff_len, total_packet_count, urb); | ||
1549 | + trb_buff_len, total_packet_count, urb, | ||
1550 | + num_trbs - 1); | ||
1551 | } | ||
1552 | length_field = TRB_LEN(trb_buff_len) | | ||
1553 | remainder | | ||
1554 | @@ -3625,7 +3630,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | ||
1555 | addr = start_addr + urb->iso_frame_desc[i].offset; | ||
1556 | td_len = urb->iso_frame_desc[i].length; | ||
1557 | td_remain_len = td_len; | ||
1558 | - total_packet_count = roundup(td_len, | ||
1559 | + total_packet_count = DIV_ROUND_UP(td_len, | ||
1560 | usb_endpoint_maxp(&urb->ep->desc)); | ||
1561 | /* A zero-length transfer still involves at least one packet. */ | ||
1562 | if (total_packet_count == 0) | ||
1563 | @@ -3704,7 +3709,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | ||
1564 | } else { | ||
1565 | remainder = xhci_v1_0_td_remainder( | ||
1566 | running_total, trb_buff_len, | ||
1567 | - total_packet_count, urb); | ||
1568 | + total_packet_count, urb, | ||
1569 | + (trbs_per_td - j - 1)); | ||
1570 | } | ||
1571 | length_field = TRB_LEN(trb_buff_len) | | ||
1572 | remainder | | ||
1573 | diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c | ||
1574 | index e52ddfe..b4063fc 100644 | ||
1575 | --- a/drivers/usb/host/xhci.c | ||
1576 | +++ b/drivers/usb/host/xhci.c | ||
1577 | @@ -480,7 +480,7 @@ static bool compliance_mode_recovery_timer_quirk_check(void) | ||
1578 | if (strstr(dmi_product_name, "Z420") || | ||
1579 | strstr(dmi_product_name, "Z620") || | ||
1580 | strstr(dmi_product_name, "Z820") || | ||
1581 | - strstr(dmi_product_name, "Z1")) | ||
1582 | + strstr(dmi_product_name, "Z1 Workstation")) | ||
1583 | return true; | ||
1584 | |||
1585 | return false; | ||
1586 | @@ -2253,7 +2253,7 @@ static bool xhci_is_async_ep(unsigned int ep_type) | ||
1587 | |||
1588 | static bool xhci_is_sync_in_ep(unsigned int ep_type) | ||
1589 | { | ||
1590 | - return (ep_type == ISOC_IN_EP || ep_type != INT_IN_EP); | ||
1591 | + return (ep_type == ISOC_IN_EP || ep_type == INT_IN_EP); | ||
1592 | } | ||
1593 | |||
1594 | static unsigned int xhci_get_ss_bw_consumed(struct xhci_bw_info *ep_bw) | ||
1595 | diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c | ||
1596 | index 66bc376..319cfcf 100644 | ||
1597 | --- a/drivers/usb/musb/cppi_dma.c | ||
1598 | +++ b/drivers/usb/musb/cppi_dma.c | ||
1599 | @@ -1313,6 +1313,7 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) | ||
1600 | |||
1601 | return IRQ_HANDLED; | ||
1602 | } | ||
1603 | +EXPORT_SYMBOL_GPL(cppi_interrupt); | ||
1604 | |||
1605 | /* Instantiate a software object representing a DMA controller. */ | ||
1606 | struct dma_controller *__init | ||
1607 | diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c | ||
1608 | index 5aa43c3..52bfd07 100644 | ||
1609 | --- a/drivers/virtio/virtio_ring.c | ||
1610 | +++ b/drivers/virtio/virtio_ring.c | ||
1611 | @@ -132,6 +132,13 @@ static int vring_add_indirect(struct vring_virtqueue *vq, | ||
1612 | unsigned head; | ||
1613 | int i; | ||
1614 | |||
1615 | + /* | ||
1616 | + * We require lowmem mappings for the descriptors because | ||
1617 | + * otherwise virt_to_phys will give us bogus addresses in the | ||
1618 | + * virtqueue. | ||
1619 | + */ | ||
1620 | + gfp &= ~(__GFP_HIGHMEM | __GFP_HIGH); | ||
1621 | + | ||
1622 | desc = kmalloc((out + in) * sizeof(struct vring_desc), gfp); | ||
1623 | if (!desc) | ||
1624 | return -ENOMEM; | ||
1625 | diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c | ||
1626 | index 613aa06..e172439 100644 | ||
1627 | --- a/fs/binfmt_misc.c | ||
1628 | +++ b/fs/binfmt_misc.c | ||
1629 | @@ -176,7 +176,10 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) | ||
1630 | goto _error; | ||
1631 | bprm->argc ++; | ||
1632 | |||
1633 | - bprm->interp = iname; /* for binfmt_script */ | ||
1634 | + /* Update interp in case binfmt_script needs it. */ | ||
1635 | + retval = bprm_change_interp(iname, bprm); | ||
1636 | + if (retval < 0) | ||
1637 | + goto _error; | ||
1638 | |||
1639 | interp_file = open_exec (iname); | ||
1640 | retval = PTR_ERR (interp_file); | ||
1641 | diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c | ||
1642 | index d3b8c1f..df49d48 100644 | ||
1643 | --- a/fs/binfmt_script.c | ||
1644 | +++ b/fs/binfmt_script.c | ||
1645 | @@ -82,7 +82,9 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs) | ||
1646 | retval = copy_strings_kernel(1, &i_name, bprm); | ||
1647 | if (retval) return retval; | ||
1648 | bprm->argc++; | ||
1649 | - bprm->interp = interp; | ||
1650 | + retval = bprm_change_interp(interp, bprm); | ||
1651 | + if (retval < 0) | ||
1652 | + return retval; | ||
1653 | |||
1654 | /* | ||
1655 | * OK, now restart the process with the interpreter's dentry. | ||
1656 | diff --git a/fs/exec.c b/fs/exec.c | ||
1657 | index 6c4791d..51d8629 100644 | ||
1658 | --- a/fs/exec.c | ||
1659 | +++ b/fs/exec.c | ||
1660 | @@ -1206,9 +1206,24 @@ void free_bprm(struct linux_binprm *bprm) | ||
1661 | mutex_unlock(¤t->signal->cred_guard_mutex); | ||
1662 | abort_creds(bprm->cred); | ||
1663 | } | ||
1664 | + /* If a binfmt changed the interp, free it. */ | ||
1665 | + if (bprm->interp != bprm->filename) | ||
1666 | + kfree(bprm->interp); | ||
1667 | kfree(bprm); | ||
1668 | } | ||
1669 | |||
1670 | +int bprm_change_interp(char *interp, struct linux_binprm *bprm) | ||
1671 | +{ | ||
1672 | + /* If a binfmt changed the interp, free it first. */ | ||
1673 | + if (bprm->interp != bprm->filename) | ||
1674 | + kfree(bprm->interp); | ||
1675 | + bprm->interp = kstrdup(interp, GFP_KERNEL); | ||
1676 | + if (!bprm->interp) | ||
1677 | + return -ENOMEM; | ||
1678 | + return 0; | ||
1679 | +} | ||
1680 | +EXPORT_SYMBOL(bprm_change_interp); | ||
1681 | + | ||
1682 | /* | ||
1683 | * install the new credentials for this executable | ||
1684 | */ | ||
1685 | diff --git a/fs/nfs/client.c b/fs/nfs/client.c | ||
1686 | index 60f7e4e..37f6de3 100644 | ||
1687 | --- a/fs/nfs/client.c | ||
1688 | +++ b/fs/nfs/client.c | ||
1689 | @@ -694,8 +694,7 @@ static int nfs_create_rpc_client(struct nfs_client *clp, | ||
1690 | */ | ||
1691 | static void nfs_destroy_server(struct nfs_server *server) | ||
1692 | { | ||
1693 | - if (!(server->flags & NFS_MOUNT_LOCAL_FLOCK) || | ||
1694 | - !(server->flags & NFS_MOUNT_LOCAL_FCNTL)) | ||
1695 | + if (server->nlm_host) | ||
1696 | nlmclnt_done(server->nlm_host); | ||
1697 | } | ||
1698 | |||
1699 | diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c | ||
1700 | index 53ad9d1..a0daac7 100644 | ||
1701 | --- a/fs/nfs/dir.c | ||
1702 | +++ b/fs/nfs/dir.c | ||
1703 | @@ -1219,11 +1219,14 @@ static int nfs_dentry_delete(const struct dentry *dentry) | ||
1704 | |||
1705 | } | ||
1706 | |||
1707 | +/* Ensure that we revalidate inode->i_nlink */ | ||
1708 | static void nfs_drop_nlink(struct inode *inode) | ||
1709 | { | ||
1710 | spin_lock(&inode->i_lock); | ||
1711 | - if (inode->i_nlink > 0) | ||
1712 | - drop_nlink(inode); | ||
1713 | + /* drop the inode if we're reasonably sure this is the last link */ | ||
1714 | + if (inode->i_nlink == 1) | ||
1715 | + clear_nlink(inode); | ||
1716 | + NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR; | ||
1717 | spin_unlock(&inode->i_lock); | ||
1718 | } | ||
1719 | |||
1720 | @@ -1238,8 +1241,8 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) | ||
1721 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA; | ||
1722 | |||
1723 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { | ||
1724 | - drop_nlink(inode); | ||
1725 | nfs_complete_unlink(dentry, inode); | ||
1726 | + nfs_drop_nlink(inode); | ||
1727 | } | ||
1728 | iput(inode); | ||
1729 | } | ||
1730 | @@ -1800,10 +1803,8 @@ static int nfs_safe_remove(struct dentry *dentry) | ||
1731 | if (inode != NULL) { | ||
1732 | nfs_inode_return_delegation(inode); | ||
1733 | error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); | ||
1734 | - /* The VFS may want to delete this inode */ | ||
1735 | if (error == 0) | ||
1736 | nfs_drop_nlink(inode); | ||
1737 | - nfs_mark_for_revalidate(inode); | ||
1738 | } else | ||
1739 | error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); | ||
1740 | if (error == -ENOENT) | ||
1741 | diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c | ||
1742 | index 8955e36..3035187 100644 | ||
1743 | --- a/fs/nfs/nfs4proc.c | ||
1744 | +++ b/fs/nfs/nfs4proc.c | ||
1745 | @@ -5739,13 +5739,26 @@ static void nfs41_sequence_prepare(struct rpc_task *task, void *data) | ||
1746 | rpc_call_start(task); | ||
1747 | } | ||
1748 | |||
1749 | +static void nfs41_sequence_prepare_privileged(struct rpc_task *task, void *data) | ||
1750 | +{ | ||
1751 | + rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED); | ||
1752 | + nfs41_sequence_prepare(task, data); | ||
1753 | +} | ||
1754 | + | ||
1755 | static const struct rpc_call_ops nfs41_sequence_ops = { | ||
1756 | .rpc_call_done = nfs41_sequence_call_done, | ||
1757 | .rpc_call_prepare = nfs41_sequence_prepare, | ||
1758 | .rpc_release = nfs41_sequence_release, | ||
1759 | }; | ||
1760 | |||
1761 | -static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred) | ||
1762 | +static const struct rpc_call_ops nfs41_sequence_privileged_ops = { | ||
1763 | + .rpc_call_done = nfs41_sequence_call_done, | ||
1764 | + .rpc_call_prepare = nfs41_sequence_prepare_privileged, | ||
1765 | + .rpc_release = nfs41_sequence_release, | ||
1766 | +}; | ||
1767 | + | ||
1768 | +static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred, | ||
1769 | + const struct rpc_call_ops *seq_ops) | ||
1770 | { | ||
1771 | struct nfs4_sequence_data *calldata; | ||
1772 | struct rpc_message msg = { | ||
1773 | @@ -5755,7 +5768,7 @@ static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_ | ||
1774 | struct rpc_task_setup task_setup_data = { | ||
1775 | .rpc_client = clp->cl_rpcclient, | ||
1776 | .rpc_message = &msg, | ||
1777 | - .callback_ops = &nfs41_sequence_ops, | ||
1778 | + .callback_ops = seq_ops, | ||
1779 | .flags = RPC_TASK_ASYNC | RPC_TASK_SOFT, | ||
1780 | }; | ||
1781 | |||
1782 | @@ -5782,7 +5795,7 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cr | ||
1783 | |||
1784 | if ((renew_flags & NFS4_RENEW_TIMEOUT) == 0) | ||
1785 | return 0; | ||
1786 | - task = _nfs41_proc_sequence(clp, cred); | ||
1787 | + task = _nfs41_proc_sequence(clp, cred, &nfs41_sequence_ops); | ||
1788 | if (IS_ERR(task)) | ||
1789 | ret = PTR_ERR(task); | ||
1790 | else | ||
1791 | @@ -5796,7 +5809,7 @@ static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred) | ||
1792 | struct rpc_task *task; | ||
1793 | int ret; | ||
1794 | |||
1795 | - task = _nfs41_proc_sequence(clp, cred); | ||
1796 | + task = _nfs41_proc_sequence(clp, cred, &nfs41_sequence_privileged_ops); | ||
1797 | if (IS_ERR(task)) { | ||
1798 | ret = PTR_ERR(task); | ||
1799 | goto out; | ||
1800 | diff --git a/fs/nfs/super.c b/fs/nfs/super.c | ||
1801 | index feabe7a..c252161 100644 | ||
1802 | --- a/fs/nfs/super.c | ||
1803 | +++ b/fs/nfs/super.c | ||
1804 | @@ -1138,7 +1138,7 @@ static int nfs_get_option_str(substring_t args[], char **option) | ||
1805 | { | ||
1806 | kfree(*option); | ||
1807 | *option = match_strdup(args); | ||
1808 | - return !option; | ||
1809 | + return !*option; | ||
1810 | } | ||
1811 | |||
1812 | static int nfs_get_option_ul(substring_t args[], unsigned long *option) | ||
1813 | diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c | ||
1814 | index 987e719..dd0308d 100644 | ||
1815 | --- a/fs/nfsd/nfs4proc.c | ||
1816 | +++ b/fs/nfsd/nfs4proc.c | ||
1817 | @@ -194,6 +194,7 @@ static __be32 | ||
1818 | do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) | ||
1819 | { | ||
1820 | struct svc_fh *resfh; | ||
1821 | + int accmode; | ||
1822 | __be32 status; | ||
1823 | |||
1824 | resfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL); | ||
1825 | @@ -253,9 +254,10 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o | ||
1826 | /* set reply cache */ | ||
1827 | fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh, | ||
1828 | &resfh->fh_handle); | ||
1829 | - if (!open->op_created) | ||
1830 | - status = do_open_permission(rqstp, resfh, open, | ||
1831 | - NFSD_MAY_NOP); | ||
1832 | + accmode = NFSD_MAY_NOP; | ||
1833 | + if (open->op_created) | ||
1834 | + accmode |= NFSD_MAY_OWNER_OVERRIDE; | ||
1835 | + status = do_open_permission(rqstp, resfh, open, accmode); | ||
1836 | set_change_info(&open->op_cinfo, current_fh); | ||
1837 | fh_dup2(current_fh, resfh); | ||
1838 | out: | ||
1839 | diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c | ||
1840 | index a2f99d1..537731e 100644 | ||
1841 | --- a/fs/nfsd/nfs4state.c | ||
1842 | +++ b/fs/nfsd/nfs4state.c | ||
1843 | @@ -2356,7 +2356,7 @@ nfsd4_init_slabs(void) | ||
1844 | if (openowner_slab == NULL) | ||
1845 | goto out_nomem; | ||
1846 | lockowner_slab = kmem_cache_create("nfsd4_lockowners", | ||
1847 | - sizeof(struct nfs4_openowner), 0, 0, NULL); | ||
1848 | + sizeof(struct nfs4_lockowner), 0, 0, NULL); | ||
1849 | if (lockowner_slab == NULL) | ||
1850 | goto out_nomem; | ||
1851 | file_slab = kmem_cache_create("nfsd4_files", | ||
1852 | diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c | ||
1853 | index 283d15e..967d68e 100644 | ||
1854 | --- a/fs/nfsd/nfs4xdr.c | ||
1855 | +++ b/fs/nfsd/nfs4xdr.c | ||
1856 | @@ -2920,11 +2920,16 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, | ||
1857 | len = maxcount; | ||
1858 | v = 0; | ||
1859 | while (len > 0) { | ||
1860 | - pn = resp->rqstp->rq_resused++; | ||
1861 | + pn = resp->rqstp->rq_resused; | ||
1862 | + if (!resp->rqstp->rq_respages[pn]) { /* ran out of pages */ | ||
1863 | + maxcount -= len; | ||
1864 | + break; | ||
1865 | + } | ||
1866 | resp->rqstp->rq_vec[v].iov_base = | ||
1867 | page_address(resp->rqstp->rq_respages[pn]); | ||
1868 | resp->rqstp->rq_vec[v].iov_len = | ||
1869 | len < PAGE_SIZE ? len : PAGE_SIZE; | ||
1870 | + resp->rqstp->rq_resused++; | ||
1871 | v++; | ||
1872 | len -= PAGE_SIZE; | ||
1873 | } | ||
1874 | @@ -2970,6 +2975,8 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd | ||
1875 | return nfserr; | ||
1876 | if (resp->xbuf->page_len) | ||
1877 | return nfserr_resource; | ||
1878 | + if (!resp->rqstp->rq_respages[resp->rqstp->rq_resused]) | ||
1879 | + return nfserr_resource; | ||
1880 | |||
1881 | page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]); | ||
1882 | |||
1883 | @@ -3019,6 +3026,8 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4 | ||
1884 | return nfserr; | ||
1885 | if (resp->xbuf->page_len) | ||
1886 | return nfserr_resource; | ||
1887 | + if (!resp->rqstp->rq_respages[resp->rqstp->rq_resused]) | ||
1888 | + return nfserr_resource; | ||
1889 | |||
1890 | RESERVE_SPACE(NFS4_VERIFIER_SIZE); | ||
1891 | savep = p; | ||
1892 | diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c | ||
1893 | index b6f8e65..53459b0 100644 | ||
1894 | --- a/fs/nfsd/nfssvc.c | ||
1895 | +++ b/fs/nfsd/nfssvc.c | ||
1896 | @@ -650,7 +650,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) | ||
1897 | } | ||
1898 | |||
1899 | /* Store reply in cache. */ | ||
1900 | - nfsd_cache_update(rqstp, proc->pc_cachetype, statp + 1); | ||
1901 | + nfsd_cache_update(rqstp, rqstp->rq_cachetype, statp + 1); | ||
1902 | return 1; | ||
1903 | } | ||
1904 | |||
1905 | diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c | ||
1906 | index 5686661..f031601 100644 | ||
1907 | --- a/fs/nfsd/vfs.c | ||
1908 | +++ b/fs/nfsd/vfs.c | ||
1909 | @@ -1477,13 +1477,19 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, | ||
1910 | case NFS3_CREATE_EXCLUSIVE: | ||
1911 | if ( dchild->d_inode->i_mtime.tv_sec == v_mtime | ||
1912 | && dchild->d_inode->i_atime.tv_sec == v_atime | ||
1913 | - && dchild->d_inode->i_size == 0 ) | ||
1914 | + && dchild->d_inode->i_size == 0 ) { | ||
1915 | + if (created) | ||
1916 | + *created = 1; | ||
1917 | break; | ||
1918 | + } | ||
1919 | case NFS4_CREATE_EXCLUSIVE4_1: | ||
1920 | if ( dchild->d_inode->i_mtime.tv_sec == v_mtime | ||
1921 | && dchild->d_inode->i_atime.tv_sec == v_atime | ||
1922 | - && dchild->d_inode->i_size == 0 ) | ||
1923 | + && dchild->d_inode->i_size == 0 ) { | ||
1924 | + if (created) | ||
1925 | + *created = 1; | ||
1926 | goto set_attr; | ||
1927 | + } | ||
1928 | /* fallthru */ | ||
1929 | case NFS3_CREATE_GUARDED: | ||
1930 | err = nfserr_exist; | ||
1931 | diff --git a/fs/splice.c b/fs/splice.c | ||
1932 | index 5cac690..bed6a3c 100644 | ||
1933 | --- a/fs/splice.c | ||
1934 | +++ b/fs/splice.c | ||
1935 | @@ -696,8 +696,10 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe, | ||
1936 | return -EINVAL; | ||
1937 | |||
1938 | more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0; | ||
1939 | - if (sd->len < sd->total_len) | ||
1940 | + | ||
1941 | + if (sd->len < sd->total_len && pipe->nrbufs > 1) | ||
1942 | more |= MSG_SENDPAGE_NOTLAST; | ||
1943 | + | ||
1944 | return file->f_op->sendpage(file, buf->page, buf->offset, | ||
1945 | sd->len, &pos, more); | ||
1946 | } | ||
1947 | diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h | ||
1948 | index f96a5b5..979ed15 100644 | ||
1949 | --- a/include/asm-generic/tlb.h | ||
1950 | +++ b/include/asm-generic/tlb.h | ||
1951 | @@ -78,6 +78,14 @@ struct mmu_gather_batch { | ||
1952 | #define MAX_GATHER_BATCH \ | ||
1953 | ((PAGE_SIZE - sizeof(struct mmu_gather_batch)) / sizeof(void *)) | ||
1954 | |||
1955 | +/* | ||
1956 | + * Limit the maximum number of mmu_gather batches to reduce a risk of soft | ||
1957 | + * lockups for non-preemptible kernels on huge machines when a lot of memory | ||
1958 | + * is zapped during unmapping. | ||
1959 | + * 10K pages freed at once should be safe even without a preemption point. | ||
1960 | + */ | ||
1961 | +#define MAX_GATHER_BATCH_COUNT (10000UL/MAX_GATHER_BATCH) | ||
1962 | + | ||
1963 | /* struct mmu_gather is an opaque type used by the mm code for passing around | ||
1964 | * any data needed by arch specific code for tlb_remove_page. | ||
1965 | */ | ||
1966 | @@ -94,6 +102,7 @@ struct mmu_gather { | ||
1967 | struct mmu_gather_batch *active; | ||
1968 | struct mmu_gather_batch local; | ||
1969 | struct page *__pages[MMU_GATHER_BUNDLE]; | ||
1970 | + unsigned int batch_count; | ||
1971 | }; | ||
1972 | |||
1973 | #define HAVE_GENERIC_MMU_GATHER | ||
1974 | diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h | ||
1975 | index 366422b..eb53e15 100644 | ||
1976 | --- a/include/linux/binfmts.h | ||
1977 | +++ b/include/linux/binfmts.h | ||
1978 | @@ -128,6 +128,7 @@ extern int setup_arg_pages(struct linux_binprm * bprm, | ||
1979 | unsigned long stack_top, | ||
1980 | int executable_stack); | ||
1981 | extern int bprm_mm_init(struct linux_binprm *bprm); | ||
1982 | +extern int bprm_change_interp(char *interp, struct linux_binprm *bprm); | ||
1983 | extern int copy_strings_kernel(int argc, const char *const *argv, | ||
1984 | struct linux_binprm *bprm); | ||
1985 | extern int prepare_bprm_creds(struct linux_binprm *bprm); | ||
1986 | diff --git a/include/linux/freezer.h b/include/linux/freezer.h | ||
1987 | index d09af4b..ee89932 100644 | ||
1988 | --- a/include/linux/freezer.h | ||
1989 | +++ b/include/linux/freezer.h | ||
1990 | @@ -75,28 +75,62 @@ static inline bool cgroup_freezing(struct task_struct *task) | ||
1991 | */ | ||
1992 | |||
1993 | |||
1994 | -/* Tell the freezer not to count the current task as freezable. */ | ||
1995 | +/** | ||
1996 | + * freezer_do_not_count - tell freezer to ignore %current | ||
1997 | + * | ||
1998 | + * Tell freezers to ignore the current task when determining whether the | ||
1999 | + * target frozen state is reached. IOW, the current task will be | ||
2000 | + * considered frozen enough by freezers. | ||
2001 | + * | ||
2002 | + * The caller shouldn't do anything which isn't allowed for a frozen task | ||
2003 | + * until freezer_cont() is called. Usually, freezer[_do_not]_count() pair | ||
2004 | + * wrap a scheduling operation and nothing much else. | ||
2005 | + */ | ||
2006 | static inline void freezer_do_not_count(void) | ||
2007 | { | ||
2008 | current->flags |= PF_FREEZER_SKIP; | ||
2009 | } | ||
2010 | |||
2011 | -/* | ||
2012 | - * Tell the freezer to count the current task as freezable again and try to | ||
2013 | - * freeze it. | ||
2014 | +/** | ||
2015 | + * freezer_count - tell freezer to stop ignoring %current | ||
2016 | + * | ||
2017 | + * Undo freezer_do_not_count(). It tells freezers that %current should be | ||
2018 | + * considered again and tries to freeze if freezing condition is already in | ||
2019 | + * effect. | ||
2020 | */ | ||
2021 | static inline void freezer_count(void) | ||
2022 | { | ||
2023 | current->flags &= ~PF_FREEZER_SKIP; | ||
2024 | + /* | ||
2025 | + * If freezing is in progress, the following paired with smp_mb() | ||
2026 | + * in freezer_should_skip() ensures that either we see %true | ||
2027 | + * freezing() or freezer_should_skip() sees !PF_FREEZER_SKIP. | ||
2028 | + */ | ||
2029 | + smp_mb(); | ||
2030 | try_to_freeze(); | ||
2031 | } | ||
2032 | |||
2033 | -/* | ||
2034 | - * Check if the task should be counted as freezable by the freezer | ||
2035 | +/** | ||
2036 | + * freezer_should_skip - whether to skip a task when determining frozen | ||
2037 | + * state is reached | ||
2038 | + * @p: task in quesion | ||
2039 | + * | ||
2040 | + * This function is used by freezers after establishing %true freezing() to | ||
2041 | + * test whether a task should be skipped when determining the target frozen | ||
2042 | + * state is reached. IOW, if this function returns %true, @p is considered | ||
2043 | + * frozen enough. | ||
2044 | */ | ||
2045 | -static inline int freezer_should_skip(struct task_struct *p) | ||
2046 | +static inline bool freezer_should_skip(struct task_struct *p) | ||
2047 | { | ||
2048 | - return !!(p->flags & PF_FREEZER_SKIP); | ||
2049 | + /* | ||
2050 | + * The following smp_mb() paired with the one in freezer_count() | ||
2051 | + * ensures that either freezer_count() sees %true freezing() or we | ||
2052 | + * see cleared %PF_FREEZER_SKIP and return %false. This makes it | ||
2053 | + * impossible for a task to slip frozen state testing after | ||
2054 | + * clearing %PF_FREEZER_SKIP. | ||
2055 | + */ | ||
2056 | + smp_mb(); | ||
2057 | + return p->flags & PF_FREEZER_SKIP; | ||
2058 | } | ||
2059 | |||
2060 | /* | ||
2061 | diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h | ||
2062 | index c88d2a9..4dabf0f 100644 | ||
2063 | --- a/include/linux/page-flags.h | ||
2064 | +++ b/include/linux/page-flags.h | ||
2065 | @@ -361,7 +361,7 @@ static inline void ClearPageCompound(struct page *page) | ||
2066 | * pages on the LRU and/or pagecache. | ||
2067 | */ | ||
2068 | TESTPAGEFLAG(Compound, compound) | ||
2069 | -__PAGEFLAG(Head, compound) | ||
2070 | +__SETPAGEFLAG(Head, compound) __CLEARPAGEFLAG(Head, compound) | ||
2071 | |||
2072 | /* | ||
2073 | * PG_reclaim is used in combination with PG_compound to mark the | ||
2074 | @@ -373,8 +373,14 @@ __PAGEFLAG(Head, compound) | ||
2075 | * PG_compound & PG_reclaim => Tail page | ||
2076 | * PG_compound & ~PG_reclaim => Head page | ||
2077 | */ | ||
2078 | +#define PG_head_mask ((1L << PG_compound)) | ||
2079 | #define PG_head_tail_mask ((1L << PG_compound) | (1L << PG_reclaim)) | ||
2080 | |||
2081 | +static inline int PageHead(struct page *page) | ||
2082 | +{ | ||
2083 | + return ((page->flags & PG_head_tail_mask) == PG_head_mask); | ||
2084 | +} | ||
2085 | + | ||
2086 | static inline int PageTail(struct page *page) | ||
2087 | { | ||
2088 | return ((page->flags & PG_head_tail_mask) == PG_head_tail_mask); | ||
2089 | diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h | ||
2090 | index bf7934f..d7dbf4e 100644 | ||
2091 | --- a/include/linux/pci_ids.h | ||
2092 | +++ b/include/linux/pci_ids.h | ||
2093 | @@ -1565,6 +1565,7 @@ | ||
2094 | #define PCI_DEVICE_ID_RICOH_RL5C476 0x0476 | ||
2095 | #define PCI_DEVICE_ID_RICOH_RL5C478 0x0478 | ||
2096 | #define PCI_DEVICE_ID_RICOH_R5C822 0x0822 | ||
2097 | +#define PCI_DEVICE_ID_RICOH_R5CE822 0xe822 | ||
2098 | #define PCI_DEVICE_ID_RICOH_R5CE823 0xe823 | ||
2099 | #define PCI_DEVICE_ID_RICOH_R5C832 0x0832 | ||
2100 | #define PCI_DEVICE_ID_RICOH_R5C843 0x0843 | ||
2101 | diff --git a/include/linux/snmp.h b/include/linux/snmp.h | ||
2102 | index 2e68f5b..a33f70f 100644 | ||
2103 | --- a/include/linux/snmp.h | ||
2104 | +++ b/include/linux/snmp.h | ||
2105 | @@ -208,7 +208,6 @@ enum | ||
2106 | LINUX_MIB_TCPDSACKOFOSENT, /* TCPDSACKOfoSent */ | ||
2107 | LINUX_MIB_TCPDSACKRECV, /* TCPDSACKRecv */ | ||
2108 | LINUX_MIB_TCPDSACKOFORECV, /* TCPDSACKOfoRecv */ | ||
2109 | - LINUX_MIB_TCPABORTONSYN, /* TCPAbortOnSyn */ | ||
2110 | LINUX_MIB_TCPABORTONDATA, /* TCPAbortOnData */ | ||
2111 | LINUX_MIB_TCPABORTONCLOSE, /* TCPAbortOnClose */ | ||
2112 | LINUX_MIB_TCPABORTONMEMORY, /* TCPAbortOnMemory */ | ||
2113 | @@ -234,6 +233,8 @@ enum | ||
2114 | LINUX_MIB_TCPREQQFULLDROP, /* TCPReqQFullDrop */ | ||
2115 | LINUX_MIB_TCPRETRANSFAIL, /* TCPRetransFail */ | ||
2116 | LINUX_MIB_TCPRCVCOALESCE, /* TCPRcvCoalesce */ | ||
2117 | + LINUX_MIB_TCPCHALLENGEACK, /* TCPChallengeACK */ | ||
2118 | + LINUX_MIB_TCPSYNCHALLENGE, /* TCPSYNChallenge */ | ||
2119 | __LINUX_MIB_MAX | ||
2120 | }; | ||
2121 | |||
2122 | diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h | ||
2123 | index dbf9aab..e9b05de 100644 | ||
2124 | --- a/include/net/inet_connection_sock.h | ||
2125 | +++ b/include/net/inet_connection_sock.h | ||
2126 | @@ -317,6 +317,7 @@ extern void inet_csk_reqsk_queue_prune(struct sock *parent, | ||
2127 | const unsigned long max_rto); | ||
2128 | |||
2129 | extern void inet_csk_destroy_sock(struct sock *sk); | ||
2130 | +extern void inet_csk_prepare_forced_close(struct sock *sk); | ||
2131 | |||
2132 | /* | ||
2133 | * LISTEN is a special case for poll.. | ||
2134 | diff --git a/include/net/tcp.h b/include/net/tcp.h | ||
2135 | index f75a04d..2757a11 100644 | ||
2136 | --- a/include/net/tcp.h | ||
2137 | +++ b/include/net/tcp.h | ||
2138 | @@ -252,6 +252,7 @@ extern int sysctl_tcp_max_ssthresh; | ||
2139 | extern int sysctl_tcp_cookie_size; | ||
2140 | extern int sysctl_tcp_thin_linear_timeouts; | ||
2141 | extern int sysctl_tcp_thin_dupack; | ||
2142 | +extern int sysctl_tcp_challenge_ack_limit; | ||
2143 | |||
2144 | extern atomic_long_t tcp_memory_allocated; | ||
2145 | extern struct percpu_counter tcp_sockets_allocated; | ||
2146 | diff --git a/kernel/cgroup.c b/kernel/cgroup.c | ||
2147 | index 762f7cc7..a5dccd4 100644 | ||
2148 | --- a/kernel/cgroup.c | ||
2149 | +++ b/kernel/cgroup.c | ||
2150 | @@ -2568,9 +2568,7 @@ static int cgroup_create_dir(struct cgroup *cgrp, struct dentry *dentry, | ||
2151 | dentry->d_fsdata = cgrp; | ||
2152 | inc_nlink(parent->d_inode); | ||
2153 | rcu_assign_pointer(cgrp->dentry, dentry); | ||
2154 | - dget(dentry); | ||
2155 | } | ||
2156 | - dput(dentry); | ||
2157 | |||
2158 | return error; | ||
2159 | } | ||
2160 | diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c | ||
2161 | index b9d1d83..7684920 100644 | ||
2162 | --- a/kernel/irq/manage.c | ||
2163 | +++ b/kernel/irq/manage.c | ||
2164 | @@ -708,6 +708,7 @@ static void | ||
2165 | irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action) | ||
2166 | { | ||
2167 | cpumask_var_t mask; | ||
2168 | + bool valid = true; | ||
2169 | |||
2170 | if (!test_and_clear_bit(IRQTF_AFFINITY, &action->thread_flags)) | ||
2171 | return; | ||
2172 | @@ -722,10 +723,18 @@ irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action) | ||
2173 | } | ||
2174 | |||
2175 | raw_spin_lock_irq(&desc->lock); | ||
2176 | - cpumask_copy(mask, desc->irq_data.affinity); | ||
2177 | + /* | ||
2178 | + * This code is triggered unconditionally. Check the affinity | ||
2179 | + * mask pointer. For CPU_MASK_OFFSTACK=n this is optimized out. | ||
2180 | + */ | ||
2181 | + if (desc->irq_data.affinity) | ||
2182 | + cpumask_copy(mask, desc->irq_data.affinity); | ||
2183 | + else | ||
2184 | + valid = false; | ||
2185 | raw_spin_unlock_irq(&desc->lock); | ||
2186 | |||
2187 | - set_cpus_allowed_ptr(current, mask); | ||
2188 | + if (valid) | ||
2189 | + set_cpus_allowed_ptr(current, mask); | ||
2190 | free_cpumask_var(mask); | ||
2191 | } | ||
2192 | #else | ||
2193 | @@ -933,6 +942,16 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | ||
2194 | */ | ||
2195 | get_task_struct(t); | ||
2196 | new->thread = t; | ||
2197 | + /* | ||
2198 | + * Tell the thread to set its affinity. This is | ||
2199 | + * important for shared interrupt handlers as we do | ||
2200 | + * not invoke setup_affinity() for the secondary | ||
2201 | + * handlers as everything is already set up. Even for | ||
2202 | + * interrupts marked with IRQF_NO_BALANCE this is | ||
2203 | + * correct as we want the thread to move to the cpu(s) | ||
2204 | + * on which the requesting code placed the interrupt. | ||
2205 | + */ | ||
2206 | + set_bit(IRQTF_AFFINITY, &new->thread_flags); | ||
2207 | } | ||
2208 | |||
2209 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) { | ||
2210 | diff --git a/lib/atomic64.c b/lib/atomic64.c | ||
2211 | index 9785378..08a4f06 100644 | ||
2212 | --- a/lib/atomic64.c | ||
2213 | +++ b/lib/atomic64.c | ||
2214 | @@ -31,7 +31,11 @@ | ||
2215 | static union { | ||
2216 | raw_spinlock_t lock; | ||
2217 | char pad[L1_CACHE_BYTES]; | ||
2218 | -} atomic64_lock[NR_LOCKS] __cacheline_aligned_in_smp; | ||
2219 | +} atomic64_lock[NR_LOCKS] __cacheline_aligned_in_smp = { | ||
2220 | + [0 ... (NR_LOCKS - 1)] = { | ||
2221 | + .lock = __RAW_SPIN_LOCK_UNLOCKED(atomic64_lock.lock), | ||
2222 | + }, | ||
2223 | +}; | ||
2224 | |||
2225 | static inline raw_spinlock_t *lock_addr(const atomic64_t *v) | ||
2226 | { | ||
2227 | @@ -173,14 +177,3 @@ int atomic64_add_unless(atomic64_t *v, long long a, long long u) | ||
2228 | return ret; | ||
2229 | } | ||
2230 | EXPORT_SYMBOL(atomic64_add_unless); | ||
2231 | - | ||
2232 | -static int init_atomic64_lock(void) | ||
2233 | -{ | ||
2234 | - int i; | ||
2235 | - | ||
2236 | - for (i = 0; i < NR_LOCKS; ++i) | ||
2237 | - raw_spin_lock_init(&atomic64_lock[i].lock); | ||
2238 | - return 0; | ||
2239 | -} | ||
2240 | - | ||
2241 | -pure_initcall(init_atomic64_lock); | ||
2242 | diff --git a/mm/memory.c b/mm/memory.c | ||
2243 | index 6105f47..024b4af 100644 | ||
2244 | --- a/mm/memory.c | ||
2245 | +++ b/mm/memory.c | ||
2246 | @@ -182,10 +182,14 @@ static int tlb_next_batch(struct mmu_gather *tlb) | ||
2247 | return 1; | ||
2248 | } | ||
2249 | |||
2250 | + if (tlb->batch_count == MAX_GATHER_BATCH_COUNT) | ||
2251 | + return 0; | ||
2252 | + | ||
2253 | batch = (void *)__get_free_pages(GFP_NOWAIT | __GFP_NOWARN, 0); | ||
2254 | if (!batch) | ||
2255 | return 0; | ||
2256 | |||
2257 | + tlb->batch_count++; | ||
2258 | batch->next = NULL; | ||
2259 | batch->nr = 0; | ||
2260 | batch->max = MAX_GATHER_BATCH; | ||
2261 | @@ -212,6 +216,7 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm) | ||
2262 | tlb->local.nr = 0; | ||
2263 | tlb->local.max = ARRAY_SIZE(tlb->__pages); | ||
2264 | tlb->active = &tlb->local; | ||
2265 | + tlb->batch_count = 0; | ||
2266 | |||
2267 | #ifdef CONFIG_HAVE_RCU_TABLE_FREE | ||
2268 | tlb->batch = NULL; | ||
2269 | diff --git a/mm/mempolicy.c b/mm/mempolicy.c | ||
2270 | index 458dede..82f1b02 100644 | ||
2271 | --- a/mm/mempolicy.c | ||
2272 | +++ b/mm/mempolicy.c | ||
2273 | @@ -2344,8 +2344,7 @@ void numa_default_policy(void) | ||
2274 | */ | ||
2275 | |||
2276 | /* | ||
2277 | - * "local" is pseudo-policy: MPOL_PREFERRED with MPOL_F_LOCAL flag | ||
2278 | - * Used only for mpol_parse_str() and mpol_to_str() | ||
2279 | + * "local" is implemented internally by MPOL_PREFERRED with MPOL_F_LOCAL flag. | ||
2280 | */ | ||
2281 | #define MPOL_LOCAL MPOL_MAX | ||
2282 | static const char * const policy_modes[] = | ||
2283 | @@ -2360,28 +2359,21 @@ static const char * const policy_modes[] = | ||
2284 | |||
2285 | #ifdef CONFIG_TMPFS | ||
2286 | /** | ||
2287 | - * mpol_parse_str - parse string to mempolicy | ||
2288 | + * mpol_parse_str - parse string to mempolicy, for tmpfs mpol mount option. | ||
2289 | * @str: string containing mempolicy to parse | ||
2290 | * @mpol: pointer to struct mempolicy pointer, returned on success. | ||
2291 | - * @no_context: flag whether to "contextualize" the mempolicy | ||
2292 | + * @unused: redundant argument, to be removed later. | ||
2293 | * | ||
2294 | * Format of input: | ||
2295 | * <mode>[=<flags>][:<nodelist>] | ||
2296 | * | ||
2297 | - * if @no_context is true, save the input nodemask in w.user_nodemask in | ||
2298 | - * the returned mempolicy. This will be used to "clone" the mempolicy in | ||
2299 | - * a specific context [cpuset] at a later time. Used to parse tmpfs mpol | ||
2300 | - * mount option. Note that if 'static' or 'relative' mode flags were | ||
2301 | - * specified, the input nodemask will already have been saved. Saving | ||
2302 | - * it again is redundant, but safe. | ||
2303 | - * | ||
2304 | * On success, returns 0, else 1 | ||
2305 | */ | ||
2306 | -int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context) | ||
2307 | +int mpol_parse_str(char *str, struct mempolicy **mpol, int unused) | ||
2308 | { | ||
2309 | struct mempolicy *new = NULL; | ||
2310 | unsigned short mode; | ||
2311 | - unsigned short uninitialized_var(mode_flags); | ||
2312 | + unsigned short mode_flags; | ||
2313 | nodemask_t nodes; | ||
2314 | char *nodelist = strchr(str, ':'); | ||
2315 | char *flags = strchr(str, '='); | ||
2316 | @@ -2469,24 +2461,23 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context) | ||
2317 | if (IS_ERR(new)) | ||
2318 | goto out; | ||
2319 | |||
2320 | - if (no_context) { | ||
2321 | - /* save for contextualization */ | ||
2322 | - new->w.user_nodemask = nodes; | ||
2323 | - } else { | ||
2324 | - int ret; | ||
2325 | - NODEMASK_SCRATCH(scratch); | ||
2326 | - if (scratch) { | ||
2327 | - task_lock(current); | ||
2328 | - ret = mpol_set_nodemask(new, &nodes, scratch); | ||
2329 | - task_unlock(current); | ||
2330 | - } else | ||
2331 | - ret = -ENOMEM; | ||
2332 | - NODEMASK_SCRATCH_FREE(scratch); | ||
2333 | - if (ret) { | ||
2334 | - mpol_put(new); | ||
2335 | - goto out; | ||
2336 | - } | ||
2337 | - } | ||
2338 | + /* | ||
2339 | + * Save nodes for mpol_to_str() to show the tmpfs mount options | ||
2340 | + * for /proc/mounts, /proc/pid/mounts and /proc/pid/mountinfo. | ||
2341 | + */ | ||
2342 | + if (mode != MPOL_PREFERRED) | ||
2343 | + new->v.nodes = nodes; | ||
2344 | + else if (nodelist) | ||
2345 | + new->v.preferred_node = first_node(nodes); | ||
2346 | + else | ||
2347 | + new->flags |= MPOL_F_LOCAL; | ||
2348 | + | ||
2349 | + /* | ||
2350 | + * Save nodes for contextualization: this will be used to "clone" | ||
2351 | + * the mempolicy in a specific context [cpuset] at a later time. | ||
2352 | + */ | ||
2353 | + new->w.user_nodemask = nodes; | ||
2354 | + | ||
2355 | err = 0; | ||
2356 | |||
2357 | out: | ||
2358 | @@ -2506,13 +2497,13 @@ out: | ||
2359 | * @buffer: to contain formatted mempolicy string | ||
2360 | * @maxlen: length of @buffer | ||
2361 | * @pol: pointer to mempolicy to be formatted | ||
2362 | - * @no_context: "context free" mempolicy - use nodemask in w.user_nodemask | ||
2363 | + * @unused: redundant argument, to be removed later. | ||
2364 | * | ||
2365 | * Convert a mempolicy into a string. | ||
2366 | * Returns the number of characters in buffer (if positive) | ||
2367 | * or an error (negative) | ||
2368 | */ | ||
2369 | -int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol, int no_context) | ||
2370 | +int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol, int unused) | ||
2371 | { | ||
2372 | char *p = buffer; | ||
2373 | int l; | ||
2374 | @@ -2538,7 +2529,7 @@ int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol, int no_context) | ||
2375 | case MPOL_PREFERRED: | ||
2376 | nodes_clear(nodes); | ||
2377 | if (flags & MPOL_F_LOCAL) | ||
2378 | - mode = MPOL_LOCAL; /* pseudo-policy */ | ||
2379 | + mode = MPOL_LOCAL; | ||
2380 | else | ||
2381 | node_set(pol->v.preferred_node, nodes); | ||
2382 | break; | ||
2383 | @@ -2546,10 +2537,7 @@ int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol, int no_context) | ||
2384 | case MPOL_BIND: | ||
2385 | /* Fall through */ | ||
2386 | case MPOL_INTERLEAVE: | ||
2387 | - if (no_context) | ||
2388 | - nodes = pol->w.user_nodemask; | ||
2389 | - else | ||
2390 | - nodes = pol->v.nodes; | ||
2391 | + nodes = pol->v.nodes; | ||
2392 | break; | ||
2393 | |||
2394 | default: | ||
2395 | diff --git a/mm/page-writeback.c b/mm/page-writeback.c | ||
2396 | index 26adea8..bc8465f 100644 | ||
2397 | --- a/mm/page-writeback.c | ||
2398 | +++ b/mm/page-writeback.c | ||
2399 | @@ -187,6 +187,18 @@ static unsigned long highmem_dirtyable_memory(unsigned long total) | ||
2400 | zone_reclaimable_pages(z) - z->dirty_balance_reserve; | ||
2401 | } | ||
2402 | /* | ||
2403 | + * Unreclaimable memory (kernel memory or anonymous memory | ||
2404 | + * without swap) can bring down the dirtyable pages below | ||
2405 | + * the zone's dirty balance reserve and the above calculation | ||
2406 | + * will underflow. However we still want to add in nodes | ||
2407 | + * which are below threshold (negative values) to get a more | ||
2408 | + * accurate calculation but make sure that the total never | ||
2409 | + * underflows. | ||
2410 | + */ | ||
2411 | + if ((long)x < 0) | ||
2412 | + x = 0; | ||
2413 | + | ||
2414 | + /* | ||
2415 | * Make sure that the number of highmem pages is never larger | ||
2416 | * than the number of the total dirtyable memory. This can only | ||
2417 | * occur in very strange VM situations but we want to make sure | ||
2418 | @@ -208,8 +220,8 @@ unsigned long global_dirtyable_memory(void) | ||
2419 | { | ||
2420 | unsigned long x; | ||
2421 | |||
2422 | - x = global_page_state(NR_FREE_PAGES) + global_reclaimable_pages() - | ||
2423 | - dirty_balance_reserve; | ||
2424 | + x = global_page_state(NR_FREE_PAGES) + global_reclaimable_pages(); | ||
2425 | + x -= min(x, dirty_balance_reserve); | ||
2426 | |||
2427 | if (!vm_highmem_is_dirtyable) | ||
2428 | x -= highmem_dirtyable_memory(x); | ||
2429 | @@ -276,9 +288,12 @@ static unsigned long zone_dirtyable_memory(struct zone *zone) | ||
2430 | * highmem zone can hold its share of dirty pages, so we don't | ||
2431 | * care about vm_highmem_is_dirtyable here. | ||
2432 | */ | ||
2433 | - return zone_page_state(zone, NR_FREE_PAGES) + | ||
2434 | - zone_reclaimable_pages(zone) - | ||
2435 | - zone->dirty_balance_reserve; | ||
2436 | + unsigned long nr_pages = zone_page_state(zone, NR_FREE_PAGES) + | ||
2437 | + zone_reclaimable_pages(zone); | ||
2438 | + | ||
2439 | + /* don't allow this to underflow */ | ||
2440 | + nr_pages -= min(nr_pages, zone->dirty_balance_reserve); | ||
2441 | + return nr_pages; | ||
2442 | } | ||
2443 | |||
2444 | /** | ||
2445 | diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c | ||
2446 | index a6d5d63..fa701b6 100644 | ||
2447 | --- a/net/batman-adv/bat_iv_ogm.c | ||
2448 | +++ b/net/batman-adv/bat_iv_ogm.c | ||
2449 | @@ -72,7 +72,7 @@ static unsigned long bat_iv_ogm_emit_send_time(const struct bat_priv *bat_priv) | ||
2450 | { | ||
2451 | return jiffies + msecs_to_jiffies( | ||
2452 | atomic_read(&bat_priv->orig_interval) - | ||
2453 | - JITTER + (random32() % 2*JITTER)); | ||
2454 | + JITTER + (random32() % (2*JITTER))); | ||
2455 | } | ||
2456 | |||
2457 | /* when do we schedule a ogm packet to be sent */ | ||
2458 | diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c | ||
2459 | index 0a30ec1..13b6c28 100644 | ||
2460 | --- a/net/bluetooth/hci_core.c | ||
2461 | +++ b/net/bluetooth/hci_core.c | ||
2462 | @@ -1866,6 +1866,8 @@ void hci_unregister_dev(struct hci_dev *hdev) | ||
2463 | for (i = 0; i < NUM_REASSEMBLY; i++) | ||
2464 | kfree_skb(hdev->reassembly[i]); | ||
2465 | |||
2466 | + cancel_work_sync(&hdev->power_on); | ||
2467 | + | ||
2468 | if (!test_bit(HCI_INIT, &hdev->flags) && | ||
2469 | !test_bit(HCI_SETUP, &hdev->dev_flags)) { | ||
2470 | hci_dev_lock(hdev); | ||
2471 | diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c | ||
2472 | index 717c43a..8d1edd7 100644 | ||
2473 | --- a/net/bluetooth/rfcomm/sock.c | ||
2474 | +++ b/net/bluetooth/rfcomm/sock.c | ||
2475 | @@ -485,7 +485,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | ||
2476 | long timeo; | ||
2477 | int err = 0; | ||
2478 | |||
2479 | - lock_sock(sk); | ||
2480 | + lock_sock_nested(sk, SINGLE_DEPTH_NESTING); | ||
2481 | |||
2482 | if (sk->sk_type != SOCK_STREAM) { | ||
2483 | err = -EINVAL; | ||
2484 | @@ -522,7 +522,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | ||
2485 | |||
2486 | release_sock(sk); | ||
2487 | timeo = schedule_timeout(timeo); | ||
2488 | - lock_sock(sk); | ||
2489 | + lock_sock_nested(sk, SINGLE_DEPTH_NESTING); | ||
2490 | } | ||
2491 | __set_current_state(TASK_RUNNING); | ||
2492 | remove_wait_queue(sk_sleep(sk), &wait); | ||
2493 | diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c | ||
2494 | index caf6e17..c6f6e42 100644 | ||
2495 | --- a/net/dccp/ipv4.c | ||
2496 | +++ b/net/dccp/ipv4.c | ||
2497 | @@ -435,8 +435,8 @@ exit: | ||
2498 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); | ||
2499 | return NULL; | ||
2500 | put_and_exit: | ||
2501 | - bh_unlock_sock(newsk); | ||
2502 | - sock_put(newsk); | ||
2503 | + inet_csk_prepare_forced_close(newsk); | ||
2504 | + dccp_done(newsk); | ||
2505 | goto exit; | ||
2506 | } | ||
2507 | |||
2508 | diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c | ||
2509 | index 4dc588f..aaa8f8b 100644 | ||
2510 | --- a/net/dccp/ipv6.c | ||
2511 | +++ b/net/dccp/ipv6.c | ||
2512 | @@ -611,7 +611,8 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | ||
2513 | newinet->inet_rcv_saddr = LOOPBACK4_IPV6; | ||
2514 | |||
2515 | if (__inet_inherit_port(sk, newsk) < 0) { | ||
2516 | - sock_put(newsk); | ||
2517 | + inet_csk_prepare_forced_close(newsk); | ||
2518 | + dccp_done(newsk); | ||
2519 | goto out; | ||
2520 | } | ||
2521 | __inet6_hash(newsk, NULL); | ||
2522 | diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c | ||
2523 | index 19d66ce..3f40432 100644 | ||
2524 | --- a/net/ipv4/inet_connection_sock.c | ||
2525 | +++ b/net/ipv4/inet_connection_sock.c | ||
2526 | @@ -659,6 +659,22 @@ void inet_csk_destroy_sock(struct sock *sk) | ||
2527 | } | ||
2528 | EXPORT_SYMBOL(inet_csk_destroy_sock); | ||
2529 | |||
2530 | +/* This function allows to force a closure of a socket after the call to | ||
2531 | + * tcp/dccp_create_openreq_child(). | ||
2532 | + */ | ||
2533 | +void inet_csk_prepare_forced_close(struct sock *sk) | ||
2534 | +{ | ||
2535 | + /* sk_clone_lock locked the socket and set refcnt to 2 */ | ||
2536 | + bh_unlock_sock(sk); | ||
2537 | + sock_put(sk); | ||
2538 | + | ||
2539 | + /* The below has to be done to allow calling inet_csk_destroy_sock */ | ||
2540 | + sock_set_flag(sk, SOCK_DEAD); | ||
2541 | + percpu_counter_inc(sk->sk_prot->orphan_count); | ||
2542 | + inet_sk(sk)->inet_num = 0; | ||
2543 | +} | ||
2544 | +EXPORT_SYMBOL(inet_csk_prepare_forced_close); | ||
2545 | + | ||
2546 | int inet_csk_listen_start(struct sock *sk, const int nr_table_entries) | ||
2547 | { | ||
2548 | struct inet_sock *inet = inet_sk(sk); | ||
2549 | diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c | ||
2550 | index dda5383..d7b862a 100644 | ||
2551 | --- a/net/ipv4/inet_diag.c | ||
2552 | +++ b/net/ipv4/inet_diag.c | ||
2553 | @@ -44,6 +44,10 @@ struct inet_diag_entry { | ||
2554 | u16 dport; | ||
2555 | u16 family; | ||
2556 | u16 userlocks; | ||
2557 | +#if IS_ENABLED(CONFIG_IPV6) | ||
2558 | + struct in6_addr saddr_storage; /* for IPv4-mapped-IPv6 addresses */ | ||
2559 | + struct in6_addr daddr_storage; /* for IPv4-mapped-IPv6 addresses */ | ||
2560 | +#endif | ||
2561 | }; | ||
2562 | |||
2563 | #define INET_DIAG_PUT(skb, attrtype, attrlen) \ | ||
2564 | @@ -419,25 +423,31 @@ static int inet_diag_bc_run(const struct nlattr *_bc, | ||
2565 | break; | ||
2566 | } | ||
2567 | |||
2568 | - if (cond->prefix_len == 0) | ||
2569 | - break; | ||
2570 | - | ||
2571 | if (op->code == INET_DIAG_BC_S_COND) | ||
2572 | addr = entry->saddr; | ||
2573 | else | ||
2574 | addr = entry->daddr; | ||
2575 | |||
2576 | + if (cond->family != AF_UNSPEC && | ||
2577 | + cond->family != entry->family) { | ||
2578 | + if (entry->family == AF_INET6 && | ||
2579 | + cond->family == AF_INET) { | ||
2580 | + if (addr[0] == 0 && addr[1] == 0 && | ||
2581 | + addr[2] == htonl(0xffff) && | ||
2582 | + bitstring_match(addr + 3, | ||
2583 | + cond->addr, | ||
2584 | + cond->prefix_len)) | ||
2585 | + break; | ||
2586 | + } | ||
2587 | + yes = 0; | ||
2588 | + break; | ||
2589 | + } | ||
2590 | + | ||
2591 | + if (cond->prefix_len == 0) | ||
2592 | + break; | ||
2593 | if (bitstring_match(addr, cond->addr, | ||
2594 | cond->prefix_len)) | ||
2595 | break; | ||
2596 | - if (entry->family == AF_INET6 && | ||
2597 | - cond->family == AF_INET) { | ||
2598 | - if (addr[0] == 0 && addr[1] == 0 && | ||
2599 | - addr[2] == htonl(0xffff) && | ||
2600 | - bitstring_match(addr + 3, cond->addr, | ||
2601 | - cond->prefix_len)) | ||
2602 | - break; | ||
2603 | - } | ||
2604 | yes = 0; | ||
2605 | break; | ||
2606 | } | ||
2607 | @@ -500,6 +510,55 @@ static int valid_cc(const void *bc, int len, int cc) | ||
2608 | return 0; | ||
2609 | } | ||
2610 | |||
2611 | +/* Validate an inet_diag_hostcond. */ | ||
2612 | +static bool valid_hostcond(const struct inet_diag_bc_op *op, int len, | ||
2613 | + int *min_len) | ||
2614 | +{ | ||
2615 | + int addr_len; | ||
2616 | + struct inet_diag_hostcond *cond; | ||
2617 | + | ||
2618 | + /* Check hostcond space. */ | ||
2619 | + *min_len += sizeof(struct inet_diag_hostcond); | ||
2620 | + if (len < *min_len) | ||
2621 | + return false; | ||
2622 | + cond = (struct inet_diag_hostcond *)(op + 1); | ||
2623 | + | ||
2624 | + /* Check address family and address length. */ | ||
2625 | + switch (cond->family) { | ||
2626 | + case AF_UNSPEC: | ||
2627 | + addr_len = 0; | ||
2628 | + break; | ||
2629 | + case AF_INET: | ||
2630 | + addr_len = sizeof(struct in_addr); | ||
2631 | + break; | ||
2632 | + case AF_INET6: | ||
2633 | + addr_len = sizeof(struct in6_addr); | ||
2634 | + break; | ||
2635 | + default: | ||
2636 | + return false; | ||
2637 | + } | ||
2638 | + *min_len += addr_len; | ||
2639 | + if (len < *min_len) | ||
2640 | + return false; | ||
2641 | + | ||
2642 | + /* Check prefix length (in bits) vs address length (in bytes). */ | ||
2643 | + if (cond->prefix_len > 8 * addr_len) | ||
2644 | + return false; | ||
2645 | + | ||
2646 | + return true; | ||
2647 | +} | ||
2648 | + | ||
2649 | +/* Validate a port comparison operator. */ | ||
2650 | +static inline bool valid_port_comparison(const struct inet_diag_bc_op *op, | ||
2651 | + int len, int *min_len) | ||
2652 | +{ | ||
2653 | + /* Port comparisons put the port in a follow-on inet_diag_bc_op. */ | ||
2654 | + *min_len += sizeof(struct inet_diag_bc_op); | ||
2655 | + if (len < *min_len) | ||
2656 | + return false; | ||
2657 | + return true; | ||
2658 | +} | ||
2659 | + | ||
2660 | static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) | ||
2661 | { | ||
2662 | const void *bc = bytecode; | ||
2663 | @@ -507,29 +566,39 @@ static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) | ||
2664 | |||
2665 | while (len > 0) { | ||
2666 | const struct inet_diag_bc_op *op = bc; | ||
2667 | + int min_len = sizeof(struct inet_diag_bc_op); | ||
2668 | |||
2669 | //printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len); | ||
2670 | switch (op->code) { | ||
2671 | - case INET_DIAG_BC_AUTO: | ||
2672 | case INET_DIAG_BC_S_COND: | ||
2673 | case INET_DIAG_BC_D_COND: | ||
2674 | + if (!valid_hostcond(bc, len, &min_len)) | ||
2675 | + return -EINVAL; | ||
2676 | + break; | ||
2677 | case INET_DIAG_BC_S_GE: | ||
2678 | case INET_DIAG_BC_S_LE: | ||
2679 | case INET_DIAG_BC_D_GE: | ||
2680 | case INET_DIAG_BC_D_LE: | ||
2681 | - case INET_DIAG_BC_JMP: | ||
2682 | - if (op->no < 4 || op->no > len + 4 || op->no & 3) | ||
2683 | - return -EINVAL; | ||
2684 | - if (op->no < len && | ||
2685 | - !valid_cc(bytecode, bytecode_len, len - op->no)) | ||
2686 | + if (!valid_port_comparison(bc, len, &min_len)) | ||
2687 | return -EINVAL; | ||
2688 | break; | ||
2689 | + case INET_DIAG_BC_AUTO: | ||
2690 | + case INET_DIAG_BC_JMP: | ||
2691 | case INET_DIAG_BC_NOP: | ||
2692 | break; | ||
2693 | default: | ||
2694 | return -EINVAL; | ||
2695 | } | ||
2696 | - if (op->yes < 4 || op->yes > len + 4 || op->yes & 3) | ||
2697 | + | ||
2698 | + if (op->code != INET_DIAG_BC_NOP) { | ||
2699 | + if (op->no < min_len || op->no > len + 4 || op->no & 3) | ||
2700 | + return -EINVAL; | ||
2701 | + if (op->no < len && | ||
2702 | + !valid_cc(bytecode, bytecode_len, len - op->no)) | ||
2703 | + return -EINVAL; | ||
2704 | + } | ||
2705 | + | ||
2706 | + if (op->yes < min_len || op->yes > len + 4 || op->yes & 3) | ||
2707 | return -EINVAL; | ||
2708 | bc += op->yes; | ||
2709 | len -= op->yes; | ||
2710 | @@ -586,6 +655,36 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, | ||
2711 | cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); | ||
2712 | } | ||
2713 | |||
2714 | +/* Get the IPv4, IPv6, or IPv4-mapped-IPv6 local and remote addresses | ||
2715 | + * from a request_sock. For IPv4-mapped-IPv6 we must map IPv4 to IPv6. | ||
2716 | + */ | ||
2717 | +static inline void inet_diag_req_addrs(const struct sock *sk, | ||
2718 | + const struct request_sock *req, | ||
2719 | + struct inet_diag_entry *entry) | ||
2720 | +{ | ||
2721 | + struct inet_request_sock *ireq = inet_rsk(req); | ||
2722 | + | ||
2723 | +#if IS_ENABLED(CONFIG_IPV6) | ||
2724 | + if (sk->sk_family == AF_INET6) { | ||
2725 | + if (req->rsk_ops->family == AF_INET6) { | ||
2726 | + entry->saddr = inet6_rsk(req)->loc_addr.s6_addr32; | ||
2727 | + entry->daddr = inet6_rsk(req)->rmt_addr.s6_addr32; | ||
2728 | + } else if (req->rsk_ops->family == AF_INET) { | ||
2729 | + ipv6_addr_set_v4mapped(ireq->loc_addr, | ||
2730 | + &entry->saddr_storage); | ||
2731 | + ipv6_addr_set_v4mapped(ireq->rmt_addr, | ||
2732 | + &entry->daddr_storage); | ||
2733 | + entry->saddr = entry->saddr_storage.s6_addr32; | ||
2734 | + entry->daddr = entry->daddr_storage.s6_addr32; | ||
2735 | + } | ||
2736 | + } else | ||
2737 | +#endif | ||
2738 | + { | ||
2739 | + entry->saddr = &ireq->loc_addr; | ||
2740 | + entry->daddr = &ireq->rmt_addr; | ||
2741 | + } | ||
2742 | +} | ||
2743 | + | ||
2744 | static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, | ||
2745 | struct request_sock *req, u32 pid, u32 seq, | ||
2746 | const struct nlmsghdr *unlh) | ||
2747 | @@ -624,8 +723,10 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, | ||
2748 | r->idiag_inode = 0; | ||
2749 | #if IS_ENABLED(CONFIG_IPV6) | ||
2750 | if (r->idiag_family == AF_INET6) { | ||
2751 | - *(struct in6_addr *)r->id.idiag_src = inet6_rsk(req)->loc_addr; | ||
2752 | - *(struct in6_addr *)r->id.idiag_dst = inet6_rsk(req)->rmt_addr; | ||
2753 | + struct inet_diag_entry entry; | ||
2754 | + inet_diag_req_addrs(sk, req, &entry); | ||
2755 | + memcpy(r->id.idiag_src, entry.saddr, sizeof(struct in6_addr)); | ||
2756 | + memcpy(r->id.idiag_dst, entry.daddr, sizeof(struct in6_addr)); | ||
2757 | } | ||
2758 | #endif | ||
2759 | nlh->nlmsg_len = skb_tail_pointer(skb) - b; | ||
2760 | @@ -683,18 +784,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, | ||
2761 | continue; | ||
2762 | |||
2763 | if (bc) { | ||
2764 | - entry.saddr = | ||
2765 | -#if IS_ENABLED(CONFIG_IPV6) | ||
2766 | - (entry.family == AF_INET6) ? | ||
2767 | - inet6_rsk(req)->loc_addr.s6_addr32 : | ||
2768 | -#endif | ||
2769 | - &ireq->loc_addr; | ||
2770 | - entry.daddr = | ||
2771 | -#if IS_ENABLED(CONFIG_IPV6) | ||
2772 | - (entry.family == AF_INET6) ? | ||
2773 | - inet6_rsk(req)->rmt_addr.s6_addr32 : | ||
2774 | -#endif | ||
2775 | - &ireq->rmt_addr; | ||
2776 | + inet_diag_req_addrs(sk, req, &entry); | ||
2777 | entry.dport = ntohs(ireq->rmt_port); | ||
2778 | |||
2779 | if (!inet_diag_bc_run(bc, &entry)) | ||
2780 | diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c | ||
2781 | index 3727e23..b7bf6e3 100644 | ||
2782 | --- a/net/ipv4/ip_fragment.c | ||
2783 | +++ b/net/ipv4/ip_fragment.c | ||
2784 | @@ -685,28 +685,27 @@ EXPORT_SYMBOL(ip_defrag); | ||
2785 | |||
2786 | struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user) | ||
2787 | { | ||
2788 | - const struct iphdr *iph; | ||
2789 | + struct iphdr iph; | ||
2790 | u32 len; | ||
2791 | |||
2792 | if (skb->protocol != htons(ETH_P_IP)) | ||
2793 | return skb; | ||
2794 | |||
2795 | - if (!pskb_may_pull(skb, sizeof(struct iphdr))) | ||
2796 | + if (!skb_copy_bits(skb, 0, &iph, sizeof(iph))) | ||
2797 | return skb; | ||
2798 | |||
2799 | - iph = ip_hdr(skb); | ||
2800 | - if (iph->ihl < 5 || iph->version != 4) | ||
2801 | + if (iph.ihl < 5 || iph.version != 4) | ||
2802 | return skb; | ||
2803 | - if (!pskb_may_pull(skb, iph->ihl*4)) | ||
2804 | - return skb; | ||
2805 | - iph = ip_hdr(skb); | ||
2806 | - len = ntohs(iph->tot_len); | ||
2807 | - if (skb->len < len || len < (iph->ihl * 4)) | ||
2808 | + | ||
2809 | + len = ntohs(iph.tot_len); | ||
2810 | + if (skb->len < len || len < (iph.ihl * 4)) | ||
2811 | return skb; | ||
2812 | |||
2813 | - if (ip_is_fragment(ip_hdr(skb))) { | ||
2814 | + if (ip_is_fragment(&iph)) { | ||
2815 | skb = skb_share_check(skb, GFP_ATOMIC); | ||
2816 | if (skb) { | ||
2817 | + if (!pskb_may_pull(skb, iph.ihl*4)) | ||
2818 | + return skb; | ||
2819 | if (pskb_trim_rcsum(skb, len)) | ||
2820 | return skb; | ||
2821 | memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); | ||
2822 | diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c | ||
2823 | index 8af0d44..2128975 100644 | ||
2824 | --- a/net/ipv4/proc.c | ||
2825 | +++ b/net/ipv4/proc.c | ||
2826 | @@ -232,7 +232,6 @@ static const struct snmp_mib snmp4_net_list[] = { | ||
2827 | SNMP_MIB_ITEM("TCPDSACKOfoSent", LINUX_MIB_TCPDSACKOFOSENT), | ||
2828 | SNMP_MIB_ITEM("TCPDSACKRecv", LINUX_MIB_TCPDSACKRECV), | ||
2829 | SNMP_MIB_ITEM("TCPDSACKOfoRecv", LINUX_MIB_TCPDSACKOFORECV), | ||
2830 | - SNMP_MIB_ITEM("TCPAbortOnSyn", LINUX_MIB_TCPABORTONSYN), | ||
2831 | SNMP_MIB_ITEM("TCPAbortOnData", LINUX_MIB_TCPABORTONDATA), | ||
2832 | SNMP_MIB_ITEM("TCPAbortOnClose", LINUX_MIB_TCPABORTONCLOSE), | ||
2833 | SNMP_MIB_ITEM("TCPAbortOnMemory", LINUX_MIB_TCPABORTONMEMORY), | ||
2834 | @@ -258,6 +257,8 @@ static const struct snmp_mib snmp4_net_list[] = { | ||
2835 | SNMP_MIB_ITEM("TCPReqQFullDrop", LINUX_MIB_TCPREQQFULLDROP), | ||
2836 | SNMP_MIB_ITEM("TCPRetransFail", LINUX_MIB_TCPRETRANSFAIL), | ||
2837 | SNMP_MIB_ITEM("TCPRcvCoalesce", LINUX_MIB_TCPRCVCOALESCE), | ||
2838 | + SNMP_MIB_ITEM("TCPChallengeACK", LINUX_MIB_TCPCHALLENGEACK), | ||
2839 | + SNMP_MIB_ITEM("TCPSYNChallenge", LINUX_MIB_TCPSYNCHALLENGE), | ||
2840 | SNMP_MIB_SENTINEL | ||
2841 | }; | ||
2842 | |||
2843 | diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c | ||
2844 | index 7a7724d..bf7a604 100644 | ||
2845 | --- a/net/ipv4/sysctl_net_ipv4.c | ||
2846 | +++ b/net/ipv4/sysctl_net_ipv4.c | ||
2847 | @@ -590,6 +590,13 @@ static struct ctl_table ipv4_table[] = { | ||
2848 | .mode = 0644, | ||
2849 | .proc_handler = proc_dointvec | ||
2850 | }, | ||
2851 | + { | ||
2852 | + .procname = "tcp_challenge_ack_limit", | ||
2853 | + .data = &sysctl_tcp_challenge_ack_limit, | ||
2854 | + .maxlen = sizeof(int), | ||
2855 | + .mode = 0644, | ||
2856 | + .proc_handler = proc_dointvec | ||
2857 | + }, | ||
2858 | #ifdef CONFIG_NET_DMA | ||
2859 | { | ||
2860 | .procname = "tcp_dma_copybreak", | ||
2861 | diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c | ||
2862 | index 3acebbd..0e0b6d0 100644 | ||
2863 | --- a/net/ipv4/tcp_input.c | ||
2864 | +++ b/net/ipv4/tcp_input.c | ||
2865 | @@ -88,6 +88,9 @@ int sysctl_tcp_app_win __read_mostly = 31; | ||
2866 | int sysctl_tcp_adv_win_scale __read_mostly = 1; | ||
2867 | EXPORT_SYMBOL(sysctl_tcp_adv_win_scale); | ||
2868 | |||
2869 | +/* rfc5961 challenge ack rate limiting */ | ||
2870 | +int sysctl_tcp_challenge_ack_limit = 100; | ||
2871 | + | ||
2872 | int sysctl_tcp_stdurg __read_mostly; | ||
2873 | int sysctl_tcp_rfc1337 __read_mostly; | ||
2874 | int sysctl_tcp_max_orphans __read_mostly = NR_FILE; | ||
2875 | @@ -3684,6 +3687,24 @@ static int tcp_process_frto(struct sock *sk, int flag) | ||
2876 | return 0; | ||
2877 | } | ||
2878 | |||
2879 | +/* RFC 5961 7 [ACK Throttling] */ | ||
2880 | +static void tcp_send_challenge_ack(struct sock *sk) | ||
2881 | +{ | ||
2882 | + /* unprotected vars, we dont care of overwrites */ | ||
2883 | + static u32 challenge_timestamp; | ||
2884 | + static unsigned int challenge_count; | ||
2885 | + u32 now = jiffies / HZ; | ||
2886 | + | ||
2887 | + if (now != challenge_timestamp) { | ||
2888 | + challenge_timestamp = now; | ||
2889 | + challenge_count = 0; | ||
2890 | + } | ||
2891 | + if (++challenge_count <= sysctl_tcp_challenge_ack_limit) { | ||
2892 | + NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPCHALLENGEACK); | ||
2893 | + tcp_send_ack(sk); | ||
2894 | + } | ||
2895 | +} | ||
2896 | + | ||
2897 | /* This routine deals with incoming acks, but not outgoing ones. */ | ||
2898 | static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | ||
2899 | { | ||
2900 | @@ -3703,8 +3724,14 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | ||
2901 | /* If the ack is older than previous acks | ||
2902 | * then we can probably ignore it. | ||
2903 | */ | ||
2904 | - if (before(ack, prior_snd_una)) | ||
2905 | + if (before(ack, prior_snd_una)) { | ||
2906 | + /* RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] */ | ||
2907 | + if (before(ack, prior_snd_una - tp->max_window)) { | ||
2908 | + tcp_send_challenge_ack(sk); | ||
2909 | + return -1; | ||
2910 | + } | ||
2911 | goto old_ack; | ||
2912 | + } | ||
2913 | |||
2914 | /* If the ack includes data we haven't sent yet, discard | ||
2915 | * this segment (RFC793 Section 3.9). | ||
2916 | @@ -5268,8 +5295,8 @@ out: | ||
2917 | /* Does PAWS and seqno based validation of an incoming segment, flags will | ||
2918 | * play significant role here. | ||
2919 | */ | ||
2920 | -static int tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, | ||
2921 | - const struct tcphdr *th, int syn_inerr) | ||
2922 | +static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, | ||
2923 | + const struct tcphdr *th, int syn_inerr) | ||
2924 | { | ||
2925 | const u8 *hash_location; | ||
2926 | struct tcp_sock *tp = tcp_sk(sk); | ||
2927 | @@ -5294,38 +5321,48 @@ static int tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, | ||
2928 | * an acknowledgment should be sent in reply (unless the RST | ||
2929 | * bit is set, if so drop the segment and return)". | ||
2930 | */ | ||
2931 | - if (!th->rst) | ||
2932 | + if (!th->rst) { | ||
2933 | + if (th->syn) | ||
2934 | + goto syn_challenge; | ||
2935 | tcp_send_dupack(sk, skb); | ||
2936 | + } | ||
2937 | goto discard; | ||
2938 | } | ||
2939 | |||
2940 | /* Step 2: check RST bit */ | ||
2941 | if (th->rst) { | ||
2942 | - tcp_reset(sk); | ||
2943 | + /* RFC 5961 3.2 : | ||
2944 | + * If sequence number exactly matches RCV.NXT, then | ||
2945 | + * RESET the connection | ||
2946 | + * else | ||
2947 | + * Send a challenge ACK | ||
2948 | + */ | ||
2949 | + if (TCP_SKB_CB(skb)->seq == tp->rcv_nxt) | ||
2950 | + tcp_reset(sk); | ||
2951 | + else | ||
2952 | + tcp_send_challenge_ack(sk); | ||
2953 | goto discard; | ||
2954 | } | ||
2955 | |||
2956 | - /* ts_recent update must be made after we are sure that the packet | ||
2957 | - * is in window. | ||
2958 | - */ | ||
2959 | - tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); | ||
2960 | - | ||
2961 | /* step 3: check security and precedence [ignored] */ | ||
2962 | |||
2963 | - /* step 4: Check for a SYN in window. */ | ||
2964 | - if (th->syn && !before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { | ||
2965 | + /* step 4: Check for a SYN | ||
2966 | + * RFC 5691 4.2 : Send a challenge ack | ||
2967 | + */ | ||
2968 | + if (th->syn) { | ||
2969 | +syn_challenge: | ||
2970 | if (syn_inerr) | ||
2971 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS); | ||
2972 | - NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPABORTONSYN); | ||
2973 | - tcp_reset(sk); | ||
2974 | - return -1; | ||
2975 | + NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSYNCHALLENGE); | ||
2976 | + tcp_send_challenge_ack(sk); | ||
2977 | + goto discard; | ||
2978 | } | ||
2979 | |||
2980 | - return 1; | ||
2981 | + return true; | ||
2982 | |||
2983 | discard: | ||
2984 | __kfree_skb(skb); | ||
2985 | - return 0; | ||
2986 | + return false; | ||
2987 | } | ||
2988 | |||
2989 | /* | ||
2990 | @@ -5355,7 +5392,6 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, | ||
2991 | const struct tcphdr *th, unsigned int len) | ||
2992 | { | ||
2993 | struct tcp_sock *tp = tcp_sk(sk); | ||
2994 | - int res; | ||
2995 | |||
2996 | /* | ||
2997 | * Header prediction. | ||
2998 | @@ -5535,14 +5571,18 @@ slow_path: | ||
2999 | * Standard slow path. | ||
3000 | */ | ||
3001 | |||
3002 | - res = tcp_validate_incoming(sk, skb, th, 1); | ||
3003 | - if (res <= 0) | ||
3004 | - return -res; | ||
3005 | + if (!tcp_validate_incoming(sk, skb, th, 1)) | ||
3006 | + return 0; | ||
3007 | |||
3008 | step5: | ||
3009 | if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) | ||
3010 | goto discard; | ||
3011 | |||
3012 | + /* ts_recent update must be made after we are sure that the packet | ||
3013 | + * is in window. | ||
3014 | + */ | ||
3015 | + tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); | ||
3016 | + | ||
3017 | tcp_rcv_rtt_measure_ts(sk, skb); | ||
3018 | |||
3019 | /* Process urgent data. */ | ||
3020 | @@ -5847,7 +5887,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | ||
3021 | struct tcp_sock *tp = tcp_sk(sk); | ||
3022 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
3023 | int queued = 0; | ||
3024 | - int res; | ||
3025 | |||
3026 | tp->rx_opt.saw_tstamp = 0; | ||
3027 | |||
3028 | @@ -5902,9 +5941,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | ||
3029 | return 0; | ||
3030 | } | ||
3031 | |||
3032 | - res = tcp_validate_incoming(sk, skb, th, 0); | ||
3033 | - if (res <= 0) | ||
3034 | - return -res; | ||
3035 | + if (!tcp_validate_incoming(sk, skb, th, 0)) | ||
3036 | + return 0; | ||
3037 | |||
3038 | /* step 5: check the ACK field */ | ||
3039 | if (th->ack) { | ||
3040 | @@ -6015,6 +6053,11 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | ||
3041 | } else | ||
3042 | goto discard; | ||
3043 | |||
3044 | + /* ts_recent update must be made after we are sure that the packet | ||
3045 | + * is in window. | ||
3046 | + */ | ||
3047 | + tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); | ||
3048 | + | ||
3049 | /* step 6: check the URG bit */ | ||
3050 | tcp_urg(sk, skb, th); | ||
3051 | |||
3052 | diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c | ||
3053 | index 8f2458d..76f50e1 100644 | ||
3054 | --- a/net/ipv4/tcp_ipv4.c | ||
3055 | +++ b/net/ipv4/tcp_ipv4.c | ||
3056 | @@ -1524,10 +1524,8 @@ exit: | ||
3057 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); | ||
3058 | return NULL; | ||
3059 | put_and_exit: | ||
3060 | - tcp_clear_xmit_timers(newsk); | ||
3061 | - tcp_cleanup_congestion_control(newsk); | ||
3062 | - bh_unlock_sock(newsk); | ||
3063 | - sock_put(newsk); | ||
3064 | + inet_csk_prepare_forced_close(newsk); | ||
3065 | + tcp_done(newsk); | ||
3066 | goto exit; | ||
3067 | } | ||
3068 | EXPORT_SYMBOL(tcp_v4_syn_recv_sock); | ||
3069 | diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c | ||
3070 | index 8a8fa2d..3889e02 100644 | ||
3071 | --- a/net/ipv6/tcp_ipv6.c | ||
3072 | +++ b/net/ipv6/tcp_ipv6.c | ||
3073 | @@ -1411,7 +1411,8 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | ||
3074 | #endif | ||
3075 | |||
3076 | if (__inet_inherit_port(sk, newsk) < 0) { | ||
3077 | - sock_put(newsk); | ||
3078 | + inet_csk_prepare_forced_close(newsk); | ||
3079 | + tcp_done(newsk); | ||
3080 | goto out; | ||
3081 | } | ||
3082 | __inet6_hash(newsk, NULL); | ||
3083 | diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c | ||
3084 | index 29b942c..f08b9166 100644 | ||
3085 | --- a/net/sched/sch_htb.c | ||
3086 | +++ b/net/sched/sch_htb.c | ||
3087 | @@ -876,7 +876,7 @@ ok: | ||
3088 | q->now = psched_get_time(); | ||
3089 | start_at = jiffies; | ||
3090 | |||
3091 | - next_event = q->now + 5 * PSCHED_TICKS_PER_SEC; | ||
3092 | + next_event = q->now + 5LLU * PSCHED_TICKS_PER_SEC; | ||
3093 | |||
3094 | for (level = 0; level < TC_HTB_MAXDEPTH; level++) { | ||
3095 | /* common case optimization - skip event handler quickly */ | ||
3096 | diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c | ||
3097 | index 6c85564..0018b65 100644 | ||
3098 | --- a/net/sctp/chunk.c | ||
3099 | +++ b/net/sctp/chunk.c | ||
3100 | @@ -183,7 +183,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, | ||
3101 | |||
3102 | msg = sctp_datamsg_new(GFP_KERNEL); | ||
3103 | if (!msg) | ||
3104 | - return NULL; | ||
3105 | + return ERR_PTR(-ENOMEM); | ||
3106 | |||
3107 | /* Note: Calculate this outside of the loop, so that all fragments | ||
3108 | * have the same expiration. | ||
3109 | @@ -280,11 +280,14 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, | ||
3110 | |||
3111 | chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0); | ||
3112 | |||
3113 | - if (!chunk) | ||
3114 | + if (!chunk) { | ||
3115 | + err = -ENOMEM; | ||
3116 | goto errout; | ||
3117 | + } | ||
3118 | + | ||
3119 | err = sctp_user_addto_chunk(chunk, offset, len, msgh->msg_iov); | ||
3120 | if (err < 0) | ||
3121 | - goto errout; | ||
3122 | + goto errout_chunk_free; | ||
3123 | |||
3124 | offset += len; | ||
3125 | |||
3126 | @@ -315,8 +318,10 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, | ||
3127 | |||
3128 | chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0); | ||
3129 | |||
3130 | - if (!chunk) | ||
3131 | + if (!chunk) { | ||
3132 | + err = -ENOMEM; | ||
3133 | goto errout; | ||
3134 | + } | ||
3135 | |||
3136 | err = sctp_user_addto_chunk(chunk, offset, over,msgh->msg_iov); | ||
3137 | |||
3138 | @@ -324,7 +329,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, | ||
3139 | __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr | ||
3140 | - (__u8 *)chunk->skb->data); | ||
3141 | if (err < 0) | ||
3142 | - goto errout; | ||
3143 | + goto errout_chunk_free; | ||
3144 | |||
3145 | sctp_datamsg_assign(msg, chunk); | ||
3146 | list_add_tail(&chunk->frag_list, &msg->chunks); | ||
3147 | @@ -332,6 +337,9 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, | ||
3148 | |||
3149 | return msg; | ||
3150 | |||
3151 | +errout_chunk_free: | ||
3152 | + sctp_chunk_free(chunk); | ||
3153 | + | ||
3154 | errout: | ||
3155 | list_for_each_safe(pos, temp, &msg->chunks) { | ||
3156 | list_del_init(pos); | ||
3157 | @@ -339,7 +347,7 @@ errout: | ||
3158 | sctp_chunk_free(chunk); | ||
3159 | } | ||
3160 | sctp_datamsg_put(msg); | ||
3161 | - return NULL; | ||
3162 | + return ERR_PTR(err); | ||
3163 | } | ||
3164 | |||
3165 | /* Check whether this message has expired. */ | ||
3166 | diff --git a/net/sctp/socket.c b/net/sctp/socket.c | ||
3167 | index dba20d6..7405355 100644 | ||
3168 | --- a/net/sctp/socket.c | ||
3169 | +++ b/net/sctp/socket.c | ||
3170 | @@ -1908,8 +1908,8 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | ||
3171 | |||
3172 | /* Break the message into multiple chunks of maximum size. */ | ||
3173 | datamsg = sctp_datamsg_from_user(asoc, sinfo, msg, msg_len); | ||
3174 | - if (!datamsg) { | ||
3175 | - err = -ENOMEM; | ||
3176 | + if (IS_ERR(datamsg)) { | ||
3177 | + err = PTR_ERR(datamsg); | ||
3178 | goto out_free; | ||
3179 | } | ||
3180 | |||
3181 | diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c | ||
3182 | index 29774e2..7f2a109 100644 | ||
3183 | --- a/sound/pci/hda/patch_realtek.c | ||
3184 | +++ b/sound/pci/hda/patch_realtek.c | ||
3185 | @@ -6520,8 +6520,8 @@ static void alc861vd_fixup_dallas(struct hda_codec *codec, | ||
3186 | const struct alc_fixup *fix, int action) | ||
3187 | { | ||
3188 | if (action == ALC_FIXUP_ACT_PRE_PROBE) { | ||
3189 | - snd_hda_override_pin_caps(codec, 0x18, 0x00001714); | ||
3190 | - snd_hda_override_pin_caps(codec, 0x19, 0x0000171c); | ||
3191 | + snd_hda_override_pin_caps(codec, 0x18, 0x00000734); | ||
3192 | + snd_hda_override_pin_caps(codec, 0x19, 0x0000073c); | ||
3193 | } | ||
3194 | } | ||
3195 | |||
3196 | diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c | ||
3197 | index 04cd44f..137b67f 100644 | ||
3198 | --- a/sound/pci/hda/patch_sigmatel.c | ||
3199 | +++ b/sound/pci/hda/patch_sigmatel.c | ||
3200 | @@ -1695,7 +1695,7 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | ||
3201 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658, | ||
3202 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), | ||
3203 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659, | ||
3204 | - "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), | ||
3205 | + "HP Pavilion dv7", STAC_HP_DV7_4000), | ||
3206 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A, | ||
3207 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), | ||
3208 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B, | ||
3209 | diff --git a/sound/usb/midi.c b/sound/usb/midi.c | ||
3210 | index eeefbce..34b9bb7 100644 | ||
3211 | --- a/sound/usb/midi.c | ||
3212 | +++ b/sound/usb/midi.c | ||
3213 | @@ -116,6 +116,7 @@ struct snd_usb_midi { | ||
3214 | struct list_head list; | ||
3215 | struct timer_list error_timer; | ||
3216 | spinlock_t disc_lock; | ||
3217 | + struct rw_semaphore disc_rwsem; | ||
3218 | struct mutex mutex; | ||
3219 | u32 usb_id; | ||
3220 | int next_midi_device; | ||
3221 | @@ -125,8 +126,10 @@ struct snd_usb_midi { | ||
3222 | struct snd_usb_midi_in_endpoint *in; | ||
3223 | } endpoints[MIDI_MAX_ENDPOINTS]; | ||
3224 | unsigned long input_triggered; | ||
3225 | - unsigned int opened; | ||
3226 | + bool autopm_reference; | ||
3227 | + unsigned int opened[2]; | ||
3228 | unsigned char disconnected; | ||
3229 | + unsigned char input_running; | ||
3230 | |||
3231 | struct snd_kcontrol *roland_load_ctl; | ||
3232 | }; | ||
3233 | @@ -148,7 +151,6 @@ struct snd_usb_midi_out_endpoint { | ||
3234 | struct snd_usb_midi_out_endpoint* ep; | ||
3235 | struct snd_rawmidi_substream *substream; | ||
3236 | int active; | ||
3237 | - bool autopm_reference; | ||
3238 | uint8_t cable; /* cable number << 4 */ | ||
3239 | uint8_t state; | ||
3240 | #define STATE_UNKNOWN 0 | ||
3241 | @@ -1033,29 +1035,58 @@ static void update_roland_altsetting(struct snd_usb_midi* umidi) | ||
3242 | snd_usbmidi_input_start(&umidi->list); | ||
3243 | } | ||
3244 | |||
3245 | -static void substream_open(struct snd_rawmidi_substream *substream, int open) | ||
3246 | +static int substream_open(struct snd_rawmidi_substream *substream, int dir, | ||
3247 | + int open) | ||
3248 | { | ||
3249 | struct snd_usb_midi* umidi = substream->rmidi->private_data; | ||
3250 | struct snd_kcontrol *ctl; | ||
3251 | + int err; | ||
3252 | + | ||
3253 | + down_read(&umidi->disc_rwsem); | ||
3254 | + if (umidi->disconnected) { | ||
3255 | + up_read(&umidi->disc_rwsem); | ||
3256 | + return open ? -ENODEV : 0; | ||
3257 | + } | ||
3258 | |||
3259 | mutex_lock(&umidi->mutex); | ||
3260 | if (open) { | ||
3261 | - if (umidi->opened++ == 0 && umidi->roland_load_ctl) { | ||
3262 | - ctl = umidi->roland_load_ctl; | ||
3263 | - ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
3264 | - snd_ctl_notify(umidi->card, | ||
3265 | + if (!umidi->opened[0] && !umidi->opened[1]) { | ||
3266 | + err = usb_autopm_get_interface(umidi->iface); | ||
3267 | + umidi->autopm_reference = err >= 0; | ||
3268 | + if (err < 0 && err != -EACCES) { | ||
3269 | + mutex_unlock(&umidi->mutex); | ||
3270 | + up_read(&umidi->disc_rwsem); | ||
3271 | + return -EIO; | ||
3272 | + } | ||
3273 | + if (umidi->roland_load_ctl) { | ||
3274 | + ctl = umidi->roland_load_ctl; | ||
3275 | + ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
3276 | + snd_ctl_notify(umidi->card, | ||
3277 | SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); | ||
3278 | - update_roland_altsetting(umidi); | ||
3279 | + update_roland_altsetting(umidi); | ||
3280 | + } | ||
3281 | } | ||
3282 | + umidi->opened[dir]++; | ||
3283 | + if (umidi->opened[1]) | ||
3284 | + snd_usbmidi_input_start(&umidi->list); | ||
3285 | } else { | ||
3286 | - if (--umidi->opened == 0 && umidi->roland_load_ctl) { | ||
3287 | - ctl = umidi->roland_load_ctl; | ||
3288 | - ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
3289 | - snd_ctl_notify(umidi->card, | ||
3290 | + umidi->opened[dir]--; | ||
3291 | + if (!umidi->opened[1]) | ||
3292 | + snd_usbmidi_input_stop(&umidi->list); | ||
3293 | + if (!umidi->opened[0] && !umidi->opened[1]) { | ||
3294 | + if (umidi->roland_load_ctl) { | ||
3295 | + ctl = umidi->roland_load_ctl; | ||
3296 | + ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
3297 | + snd_ctl_notify(umidi->card, | ||
3298 | SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); | ||
3299 | + } | ||
3300 | + if (umidi->autopm_reference) | ||
3301 | + usb_autopm_put_interface(umidi->iface); | ||
3302 | } | ||
3303 | } | ||
3304 | mutex_unlock(&umidi->mutex); | ||
3305 | + up_read(&umidi->disc_rwsem); | ||
3306 | + return 0; | ||
3307 | } | ||
3308 | |||
3309 | static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) | ||
3310 | @@ -1063,7 +1094,6 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) | ||
3311 | struct snd_usb_midi* umidi = substream->rmidi->private_data; | ||
3312 | struct usbmidi_out_port* port = NULL; | ||
3313 | int i, j; | ||
3314 | - int err; | ||
3315 | |||
3316 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) | ||
3317 | if (umidi->endpoints[i].out) | ||
3318 | @@ -1076,25 +1106,15 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) | ||
3319 | snd_BUG(); | ||
3320 | return -ENXIO; | ||
3321 | } | ||
3322 | - err = usb_autopm_get_interface(umidi->iface); | ||
3323 | - port->autopm_reference = err >= 0; | ||
3324 | - if (err < 0 && err != -EACCES) | ||
3325 | - return -EIO; | ||
3326 | + | ||
3327 | substream->runtime->private_data = port; | ||
3328 | port->state = STATE_UNKNOWN; | ||
3329 | - substream_open(substream, 1); | ||
3330 | - return 0; | ||
3331 | + return substream_open(substream, 0, 1); | ||
3332 | } | ||
3333 | |||
3334 | static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) | ||
3335 | { | ||
3336 | - struct snd_usb_midi* umidi = substream->rmidi->private_data; | ||
3337 | - struct usbmidi_out_port *port = substream->runtime->private_data; | ||
3338 | - | ||
3339 | - substream_open(substream, 0); | ||
3340 | - if (port->autopm_reference) | ||
3341 | - usb_autopm_put_interface(umidi->iface); | ||
3342 | - return 0; | ||
3343 | + return substream_open(substream, 0, 0); | ||
3344 | } | ||
3345 | |||
3346 | static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream, int up) | ||
3347 | @@ -1147,14 +1167,12 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream) | ||
3348 | |||
3349 | static int snd_usbmidi_input_open(struct snd_rawmidi_substream *substream) | ||
3350 | { | ||
3351 | - substream_open(substream, 1); | ||
3352 | - return 0; | ||
3353 | + return substream_open(substream, 1, 1); | ||
3354 | } | ||
3355 | |||
3356 | static int snd_usbmidi_input_close(struct snd_rawmidi_substream *substream) | ||
3357 | { | ||
3358 | - substream_open(substream, 0); | ||
3359 | - return 0; | ||
3360 | + return substream_open(substream, 1, 0); | ||
3361 | } | ||
3362 | |||
3363 | static void snd_usbmidi_input_trigger(struct snd_rawmidi_substream *substream, int up) | ||
3364 | @@ -1403,9 +1421,12 @@ void snd_usbmidi_disconnect(struct list_head* p) | ||
3365 | * a timer may submit an URB. To reliably break the cycle | ||
3366 | * a flag under lock must be used | ||
3367 | */ | ||
3368 | + down_write(&umidi->disc_rwsem); | ||
3369 | spin_lock_irq(&umidi->disc_lock); | ||
3370 | umidi->disconnected = 1; | ||
3371 | spin_unlock_irq(&umidi->disc_lock); | ||
3372 | + up_write(&umidi->disc_rwsem); | ||
3373 | + | ||
3374 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { | ||
3375 | struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i]; | ||
3376 | if (ep->out) | ||
3377 | @@ -2060,12 +2081,15 @@ void snd_usbmidi_input_stop(struct list_head* p) | ||
3378 | unsigned int i, j; | ||
3379 | |||
3380 | umidi = list_entry(p, struct snd_usb_midi, list); | ||
3381 | + if (!umidi->input_running) | ||
3382 | + return; | ||
3383 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { | ||
3384 | struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i]; | ||
3385 | if (ep->in) | ||
3386 | for (j = 0; j < INPUT_URBS; ++j) | ||
3387 | usb_kill_urb(ep->in->urbs[j]); | ||
3388 | } | ||
3389 | + umidi->input_running = 0; | ||
3390 | } | ||
3391 | |||
3392 | static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint* ep) | ||
3393 | @@ -2090,8 +2114,11 @@ void snd_usbmidi_input_start(struct list_head* p) | ||
3394 | int i; | ||
3395 | |||
3396 | umidi = list_entry(p, struct snd_usb_midi, list); | ||
3397 | + if (umidi->input_running || !umidi->opened[1]) | ||
3398 | + return; | ||
3399 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) | ||
3400 | snd_usbmidi_input_start_ep(umidi->endpoints[i].in); | ||
3401 | + umidi->input_running = 1; | ||
3402 | } | ||
3403 | |||
3404 | /* | ||
3405 | @@ -2117,6 +2144,7 @@ int snd_usbmidi_create(struct snd_card *card, | ||
3406 | umidi->usb_protocol_ops = &snd_usbmidi_standard_ops; | ||
3407 | init_timer(&umidi->error_timer); | ||
3408 | spin_lock_init(&umidi->disc_lock); | ||
3409 | + init_rwsem(&umidi->disc_rwsem); | ||
3410 | mutex_init(&umidi->mutex); | ||
3411 | umidi->usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor), | ||
3412 | le16_to_cpu(umidi->dev->descriptor.idProduct)); | ||
3413 | @@ -2229,9 +2257,6 @@ int snd_usbmidi_create(struct snd_card *card, | ||
3414 | } | ||
3415 | |||
3416 | list_add_tail(&umidi->list, midi_list); | ||
3417 | - | ||
3418 | - for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) | ||
3419 | - snd_usbmidi_input_start_ep(umidi->endpoints[i].in); | ||
3420 | return 0; | ||
3421 | } | ||
3422 |