1 |
Author: psomas |
2 |
Date: 2011-12-22 12:04:33 +0000 (Thu, 22 Dec 2011) |
3 |
New Revision: 2036 |
4 |
|
5 |
Added: |
6 |
genpatches-2.6/trunk/2.6.32/1050_linux-2.6.32.51.patch |
7 |
Modified: |
8 |
genpatches-2.6/trunk/2.6.32/0000_README |
9 |
Log: |
10 |
Linux patch 2.6.32.51 |
11 |
|
12 |
Modified: genpatches-2.6/trunk/2.6.32/0000_README |
13 |
=================================================================== |
14 |
--- genpatches-2.6/trunk/2.6.32/0000_README 2011-12-22 12:04:04 UTC (rev 2035) |
15 |
+++ genpatches-2.6/trunk/2.6.32/0000_README 2011-12-22 12:04:33 UTC (rev 2036) |
16 |
@@ -239,6 +239,10 @@ |
17 |
From: http://www.kernel.org |
18 |
Desc: Linux 2.6.32.50 |
19 |
|
20 |
+Patch: 1050_2.6.32.51.patch |
21 |
+From: http://www.kernel.org |
22 |
+Desc: Linux 2.6.32.51 |
23 |
+ |
24 |
Patch: 4200_fbcondecor-0.9.6.patch |
25 |
From: http://dev.gentoo.org/~spock |
26 |
Desc: Bootsplash successor by Michal Januszewski |
27 |
|
28 |
Added: genpatches-2.6/trunk/2.6.32/1050_linux-2.6.32.51.patch |
29 |
=================================================================== |
30 |
--- genpatches-2.6/trunk/2.6.32/1050_linux-2.6.32.51.patch (rev 0) |
31 |
+++ genpatches-2.6/trunk/2.6.32/1050_linux-2.6.32.51.patch 2011-12-22 12:04:33 UTC (rev 2036) |
32 |
@@ -0,0 +1,575 @@ |
33 |
+diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c |
34 |
+index 24e0e13..6b25227 100644 |
35 |
+--- a/arch/arm/mach-davinci/board-dm646x-evm.c |
36 |
++++ b/arch/arm/mach-davinci/board-dm646x-evm.c |
37 |
+@@ -502,7 +502,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) |
38 |
+ int val; |
39 |
+ u32 value; |
40 |
+ |
41 |
+- if (!vpif_vsclkdis_reg || !cpld_client) |
42 |
++ if (!vpif_vidclkctl_reg || !cpld_client) |
43 |
+ return -ENXIO; |
44 |
+ |
45 |
+ val = i2c_smbus_read_byte(cpld_client); |
46 |
+@@ -510,7 +510,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) |
47 |
+ return val; |
48 |
+ |
49 |
+ spin_lock_irqsave(&vpif_reg_lock, flags); |
50 |
+- value = __raw_readl(vpif_vsclkdis_reg); |
51 |
++ value = __raw_readl(vpif_vidclkctl_reg); |
52 |
+ if (mux_mode) { |
53 |
+ val &= VPIF_INPUT_TWO_CHANNEL; |
54 |
+ value |= VIDCH1CLK; |
55 |
+@@ -518,7 +518,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) |
56 |
+ val |= VPIF_INPUT_ONE_CHANNEL; |
57 |
+ value &= ~VIDCH1CLK; |
58 |
+ } |
59 |
+- __raw_writel(value, vpif_vsclkdis_reg); |
60 |
++ __raw_writel(value, vpif_vidclkctl_reg); |
61 |
+ spin_unlock_irqrestore(&vpif_reg_lock, flags); |
62 |
+ |
63 |
+ err = i2c_smbus_write_byte(cpld_client, val); |
64 |
+diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c |
65 |
+index 044897b..829edf0 100644 |
66 |
+--- a/arch/x86/oprofile/backtrace.c |
67 |
++++ b/arch/x86/oprofile/backtrace.c |
68 |
+@@ -11,6 +11,8 @@ |
69 |
+ #include <linux/oprofile.h> |
70 |
+ #include <linux/sched.h> |
71 |
+ #include <linux/mm.h> |
72 |
++#include <linux/highmem.h> |
73 |
++ |
74 |
+ #include <asm/ptrace.h> |
75 |
+ #include <asm/uaccess.h> |
76 |
+ #include <asm/stacktrace.h> |
77 |
+@@ -47,6 +49,42 @@ static struct stacktrace_ops backtrace_ops = { |
78 |
+ .address = backtrace_address, |
79 |
+ }; |
80 |
+ |
81 |
++/* from arch/x86/kernel/cpu/perf_event.c: */ |
82 |
++ |
83 |
++/* |
84 |
++ * best effort, GUP based copy_from_user() that assumes IRQ or NMI context |
85 |
++ */ |
86 |
++static unsigned long |
87 |
++copy_from_user_nmi(void *to, const void __user *from, unsigned long n) |
88 |
++{ |
89 |
++ unsigned long offset, addr = (unsigned long)from; |
90 |
++ unsigned long size, len = 0; |
91 |
++ struct page *page; |
92 |
++ void *map; |
93 |
++ int ret; |
94 |
++ |
95 |
++ do { |
96 |
++ ret = __get_user_pages_fast(addr, 1, 0, &page); |
97 |
++ if (!ret) |
98 |
++ break; |
99 |
++ |
100 |
++ offset = addr & (PAGE_SIZE - 1); |
101 |
++ size = min(PAGE_SIZE - offset, n - len); |
102 |
++ |
103 |
++ map = kmap_atomic(page, KM_USER0); |
104 |
++ memcpy(to, map+offset, size); |
105 |
++ kunmap_atomic(map, KM_USER0); |
106 |
++ put_page(page); |
107 |
++ |
108 |
++ len += size; |
109 |
++ to += size; |
110 |
++ addr += size; |
111 |
++ |
112 |
++ } while (len < n); |
113 |
++ |
114 |
++ return len; |
115 |
++} |
116 |
++ |
117 |
+ struct frame_head { |
118 |
+ struct frame_head *bp; |
119 |
+ unsigned long ret; |
120 |
+@@ -54,12 +92,12 @@ struct frame_head { |
121 |
+ |
122 |
+ static struct frame_head *dump_user_backtrace(struct frame_head *head) |
123 |
+ { |
124 |
++ /* Also check accessibility of one struct frame_head beyond: */ |
125 |
+ struct frame_head bufhead[2]; |
126 |
++ unsigned long bytes; |
127 |
+ |
128 |
+- /* Also check accessibility of one struct frame_head beyond */ |
129 |
+- if (!access_ok(VERIFY_READ, head, sizeof(bufhead))) |
130 |
+- return NULL; |
131 |
+- if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead))) |
132 |
++ bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead)); |
133 |
++ if (bytes != sizeof(bufhead)) |
134 |
+ return NULL; |
135 |
+ |
136 |
+ oprofile_add_trace(bufhead[0].ret); |
137 |
+diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c |
138 |
+index ca6b336..8f0e49b 100644 |
139 |
+--- a/arch/x86/oprofile/nmi_int.c |
140 |
++++ b/arch/x86/oprofile/nmi_int.c |
141 |
+@@ -750,12 +750,12 @@ int __init op_nmi_init(struct oprofile_operations *ops) |
142 |
+ |
143 |
+ void op_nmi_exit(void) |
144 |
+ { |
145 |
+- if (using_nmi) { |
146 |
+- exit_sysfs(); |
147 |
++ if (!using_nmi) |
148 |
++ return; |
149 |
++ exit_sysfs(); |
150 |
+ #ifdef CONFIG_SMP |
151 |
+- unregister_cpu_notifier(&oprofile_cpu_nb); |
152 |
++ unregister_cpu_notifier(&oprofile_cpu_nb); |
153 |
+ #endif |
154 |
+- } |
155 |
+ if (model->exit) |
156 |
+ model->exit(); |
157 |
+ } |
158 |
+diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c |
159 |
+index 5c4df24..334ccd6 100644 |
160 |
+--- a/drivers/oprofile/buffer_sync.c |
161 |
++++ b/drivers/oprofile/buffer_sync.c |
162 |
+@@ -140,6 +140,13 @@ static struct notifier_block module_load_nb = { |
163 |
+ .notifier_call = module_load_notify, |
164 |
+ }; |
165 |
+ |
166 |
++static void free_all_tasks(void) |
167 |
++{ |
168 |
++ /* make sure we don't leak task structs */ |
169 |
++ process_task_mortuary(); |
170 |
++ process_task_mortuary(); |
171 |
++} |
172 |
++ |
173 |
+ int sync_start(void) |
174 |
+ { |
175 |
+ int err; |
176 |
+@@ -147,8 +154,6 @@ int sync_start(void) |
177 |
+ if (!zalloc_cpumask_var(&marked_cpus, GFP_KERNEL)) |
178 |
+ return -ENOMEM; |
179 |
+ |
180 |
+- mutex_lock(&buffer_mutex); |
181 |
+- |
182 |
+ err = task_handoff_register(&task_free_nb); |
183 |
+ if (err) |
184 |
+ goto out1; |
185 |
+@@ -165,7 +170,6 @@ int sync_start(void) |
186 |
+ start_cpu_work(); |
187 |
+ |
188 |
+ out: |
189 |
+- mutex_unlock(&buffer_mutex); |
190 |
+ return err; |
191 |
+ out4: |
192 |
+ profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); |
193 |
+@@ -173,6 +177,7 @@ out3: |
194 |
+ profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); |
195 |
+ out2: |
196 |
+ task_handoff_unregister(&task_free_nb); |
197 |
++ free_all_tasks(); |
198 |
+ out1: |
199 |
+ free_cpumask_var(marked_cpus); |
200 |
+ goto out; |
201 |
+@@ -181,20 +186,16 @@ out1: |
202 |
+ |
203 |
+ void sync_stop(void) |
204 |
+ { |
205 |
+- /* flush buffers */ |
206 |
+- mutex_lock(&buffer_mutex); |
207 |
+ end_cpu_work(); |
208 |
+ unregister_module_notifier(&module_load_nb); |
209 |
+ profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); |
210 |
+ profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); |
211 |
+ task_handoff_unregister(&task_free_nb); |
212 |
+- mutex_unlock(&buffer_mutex); |
213 |
+- flush_scheduled_work(); |
214 |
++ barrier(); /* do all of the above first */ |
215 |
+ |
216 |
+- /* make sure we don't leak task structs */ |
217 |
+- process_task_mortuary(); |
218 |
+- process_task_mortuary(); |
219 |
++ flush_scheduled_work(); |
220 |
+ |
221 |
++ free_all_tasks(); |
222 |
+ free_cpumask_var(marked_cpus); |
223 |
+ } |
224 |
+ |
225 |
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c |
226 |
+index 9d3d8cf..cec9bff 100644 |
227 |
+--- a/drivers/usb/class/cdc-acm.c |
228 |
++++ b/drivers/usb/class/cdc-acm.c |
229 |
+@@ -1528,6 +1528,16 @@ static struct usb_device_id acm_ids[] = { |
230 |
+ }, |
231 |
+ { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */ |
232 |
+ }, |
233 |
++ /* Motorola H24 HSPA module: */ |
234 |
++ { USB_DEVICE(0x22b8, 0x2d91) }, /* modem */ |
235 |
++ { USB_DEVICE(0x22b8, 0x2d92) }, /* modem + diagnostics */ |
236 |
++ { USB_DEVICE(0x22b8, 0x2d93) }, /* modem + AT port */ |
237 |
++ { USB_DEVICE(0x22b8, 0x2d95) }, /* modem + AT port + diagnostics */ |
238 |
++ { USB_DEVICE(0x22b8, 0x2d96) }, /* modem + NMEA */ |
239 |
++ { USB_DEVICE(0x22b8, 0x2d97) }, /* modem + diagnostics + NMEA */ |
240 |
++ { USB_DEVICE(0x22b8, 0x2d99) }, /* modem + AT port + NMEA */ |
241 |
++ { USB_DEVICE(0x22b8, 0x2d9a) }, /* modem + AT port + diagnostics + NMEA */ |
242 |
++ |
243 |
+ { USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */ |
244 |
+ .driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on |
245 |
+ data interface instead of |
246 |
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c |
247 |
+index 8572c79..72ba88f 100644 |
248 |
+--- a/fs/ext4/inode.c |
249 |
++++ b/fs/ext4/inode.c |
250 |
+@@ -3228,7 +3228,7 @@ static int ext4_da_write_end(struct file *file, |
251 |
+ */ |
252 |
+ |
253 |
+ new_i_size = pos + copied; |
254 |
+- if (new_i_size > EXT4_I(inode)->i_disksize) { |
255 |
++ if (copied && new_i_size > EXT4_I(inode)->i_disksize) { |
256 |
+ if (ext4_da_should_update_i_disksize(page, end)) { |
257 |
+ down_write(&EXT4_I(inode)->i_data_sem); |
258 |
+ if (new_i_size > EXT4_I(inode)->i_disksize) { |
259 |
+diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c |
260 |
+index 052f214..0609e71 100644 |
261 |
+--- a/fs/hfs/btree.c |
262 |
++++ b/fs/hfs/btree.c |
263 |
+@@ -45,11 +45,26 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke |
264 |
+ case HFS_EXT_CNID: |
265 |
+ hfs_inode_read_fork(tree->inode, mdb->drXTExtRec, mdb->drXTFlSize, |
266 |
+ mdb->drXTFlSize, be32_to_cpu(mdb->drXTClpSiz)); |
267 |
++ if (HFS_I(tree->inode)->alloc_blocks > |
268 |
++ HFS_I(tree->inode)->first_blocks) { |
269 |
++ printk(KERN_ERR "hfs: invalid btree extent records\n"); |
270 |
++ unlock_new_inode(tree->inode); |
271 |
++ goto free_inode; |
272 |
++ } |
273 |
++ |
274 |
+ tree->inode->i_mapping->a_ops = &hfs_btree_aops; |
275 |
+ break; |
276 |
+ case HFS_CAT_CNID: |
277 |
+ hfs_inode_read_fork(tree->inode, mdb->drCTExtRec, mdb->drCTFlSize, |
278 |
+ mdb->drCTFlSize, be32_to_cpu(mdb->drCTClpSiz)); |
279 |
++ |
280 |
++ if (!HFS_I(tree->inode)->first_blocks) { |
281 |
++ printk(KERN_ERR "hfs: invalid btree extent records " |
282 |
++ "(0 size).\n"); |
283 |
++ unlock_new_inode(tree->inode); |
284 |
++ goto free_inode; |
285 |
++ } |
286 |
++ |
287 |
+ tree->inode->i_mapping->a_ops = &hfs_btree_aops; |
288 |
+ break; |
289 |
+ default: |
290 |
+@@ -58,11 +73,6 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke |
291 |
+ } |
292 |
+ unlock_new_inode(tree->inode); |
293 |
+ |
294 |
+- if (!HFS_I(tree->inode)->first_blocks) { |
295 |
+- printk(KERN_ERR "hfs: invalid btree extent records (0 size).\n"); |
296 |
+- goto free_inode; |
297 |
+- } |
298 |
+- |
299 |
+ mapping = tree->inode->i_mapping; |
300 |
+ page = read_mapping_page(mapping, 0, NULL); |
301 |
+ if (IS_ERR(page)) |
302 |
+diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c |
303 |
+index 45905ff..70713d5 100644 |
304 |
+--- a/fs/jbd/journal.c |
305 |
++++ b/fs/jbd/journal.c |
306 |
+@@ -1070,6 +1070,14 @@ static int journal_get_superblock(journal_t *journal) |
307 |
+ goto out; |
308 |
+ } |
309 |
+ |
310 |
++ if (be32_to_cpu(sb->s_first) == 0 || |
311 |
++ be32_to_cpu(sb->s_first) >= journal->j_maxlen) { |
312 |
++ printk(KERN_WARNING |
313 |
++ "JBD: Invalid start block of journal: %u\n", |
314 |
++ be32_to_cpu(sb->s_first)); |
315 |
++ goto out; |
316 |
++ } |
317 |
++ |
318 |
+ return 0; |
319 |
+ |
320 |
+ out: |
321 |
+diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c |
322 |
+index 17af879..c00de9c 100644 |
323 |
+--- a/fs/jbd2/journal.c |
324 |
++++ b/fs/jbd2/journal.c |
325 |
+@@ -1183,6 +1183,14 @@ static int journal_get_superblock(journal_t *journal) |
326 |
+ goto out; |
327 |
+ } |
328 |
+ |
329 |
++ if (be32_to_cpu(sb->s_first) == 0 || |
330 |
++ be32_to_cpu(sb->s_first) >= journal->j_maxlen) { |
331 |
++ printk(KERN_WARNING |
332 |
++ "JBD2: Invalid start block of journal: %u\n", |
333 |
++ be32_to_cpu(sb->s_first)); |
334 |
++ goto out; |
335 |
++ } |
336 |
++ |
337 |
+ return 0; |
338 |
+ |
339 |
+ out: |
340 |
+diff --git a/include/linux/log2.h b/include/linux/log2.h |
341 |
+index 25b8086..fd7ff3d 100644 |
342 |
+--- a/include/linux/log2.h |
343 |
++++ b/include/linux/log2.h |
344 |
+@@ -185,7 +185,6 @@ unsigned long __rounddown_pow_of_two(unsigned long n) |
345 |
+ #define rounddown_pow_of_two(n) \ |
346 |
+ ( \ |
347 |
+ __builtin_constant_p(n) ? ( \ |
348 |
+- (n == 1) ? 0 : \ |
349 |
+ (1UL << ilog2(n))) : \ |
350 |
+ __rounddown_pow_of_two(n) \ |
351 |
+ ) |
352 |
+diff --git a/kernel/taskstats.c b/kernel/taskstats.c |
353 |
+index b080920..a4ef542 100644 |
354 |
+--- a/kernel/taskstats.c |
355 |
++++ b/kernel/taskstats.c |
356 |
+@@ -592,6 +592,7 @@ static struct genl_ops taskstats_ops = { |
357 |
+ .cmd = TASKSTATS_CMD_GET, |
358 |
+ .doit = taskstats_user_cmd, |
359 |
+ .policy = taskstats_cmd_get_policy, |
360 |
++ .flags = GENL_ADMIN_PERM, |
361 |
+ }; |
362 |
+ |
363 |
+ static struct genl_ops cgroupstats_ops = { |
364 |
+diff --git a/mm/percpu.c b/mm/percpu.c |
365 |
+index 3bfd6e2..c90614a 100644 |
366 |
+--- a/mm/percpu.c |
367 |
++++ b/mm/percpu.c |
368 |
+@@ -110,9 +110,9 @@ static int pcpu_atom_size __read_mostly; |
369 |
+ static int pcpu_nr_slots __read_mostly; |
370 |
+ static size_t pcpu_chunk_struct_size __read_mostly; |
371 |
+ |
372 |
+-/* cpus with the lowest and highest unit numbers */ |
373 |
+-static unsigned int pcpu_first_unit_cpu __read_mostly; |
374 |
+-static unsigned int pcpu_last_unit_cpu __read_mostly; |
375 |
++/* cpus with the lowest and highest unit addresses */ |
376 |
++static unsigned int pcpu_low_unit_cpu __read_mostly; |
377 |
++static unsigned int pcpu_high_unit_cpu __read_mostly; |
378 |
+ |
379 |
+ /* the address of the first chunk which starts with the kernel static area */ |
380 |
+ void *pcpu_base_addr __read_mostly; |
381 |
+@@ -746,8 +746,8 @@ static void pcpu_pre_unmap_flush(struct pcpu_chunk *chunk, |
382 |
+ int page_start, int page_end) |
383 |
+ { |
384 |
+ flush_cache_vunmap( |
385 |
+- pcpu_chunk_addr(chunk, pcpu_first_unit_cpu, page_start), |
386 |
+- pcpu_chunk_addr(chunk, pcpu_last_unit_cpu, page_end)); |
387 |
++ pcpu_chunk_addr(chunk, pcpu_low_unit_cpu, page_start), |
388 |
++ pcpu_chunk_addr(chunk, pcpu_high_unit_cpu, page_end)); |
389 |
+ } |
390 |
+ |
391 |
+ static void __pcpu_unmap_pages(unsigned long addr, int nr_pages) |
392 |
+@@ -809,8 +809,8 @@ static void pcpu_post_unmap_tlb_flush(struct pcpu_chunk *chunk, |
393 |
+ int page_start, int page_end) |
394 |
+ { |
395 |
+ flush_tlb_kernel_range( |
396 |
+- pcpu_chunk_addr(chunk, pcpu_first_unit_cpu, page_start), |
397 |
+- pcpu_chunk_addr(chunk, pcpu_last_unit_cpu, page_end)); |
398 |
++ pcpu_chunk_addr(chunk, pcpu_low_unit_cpu, page_start), |
399 |
++ pcpu_chunk_addr(chunk, pcpu_high_unit_cpu, page_end)); |
400 |
+ } |
401 |
+ |
402 |
+ static int __pcpu_map_pages(unsigned long addr, struct page **pages, |
403 |
+@@ -887,8 +887,8 @@ static void pcpu_post_map_flush(struct pcpu_chunk *chunk, |
404 |
+ int page_start, int page_end) |
405 |
+ { |
406 |
+ flush_cache_vmap( |
407 |
+- pcpu_chunk_addr(chunk, pcpu_first_unit_cpu, page_start), |
408 |
+- pcpu_chunk_addr(chunk, pcpu_last_unit_cpu, page_end)); |
409 |
++ pcpu_chunk_addr(chunk, pcpu_low_unit_cpu, page_start), |
410 |
++ pcpu_chunk_addr(chunk, pcpu_high_unit_cpu, page_end)); |
411 |
+ } |
412 |
+ |
413 |
+ /** |
414 |
+@@ -1680,7 +1680,9 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, |
415 |
+ |
416 |
+ for (cpu = 0; cpu < nr_cpu_ids; cpu++) |
417 |
+ unit_map[cpu] = UINT_MAX; |
418 |
+- pcpu_first_unit_cpu = NR_CPUS; |
419 |
++ |
420 |
++ pcpu_low_unit_cpu = NR_CPUS; |
421 |
++ pcpu_high_unit_cpu = NR_CPUS; |
422 |
+ |
423 |
+ for (group = 0, unit = 0; group < ai->nr_groups; group++, unit += i) { |
424 |
+ const struct pcpu_group_info *gi = &ai->groups[group]; |
425 |
+@@ -1700,9 +1702,13 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, |
426 |
+ unit_map[cpu] = unit + i; |
427 |
+ unit_off[cpu] = gi->base_offset + i * ai->unit_size; |
428 |
+ |
429 |
+- if (pcpu_first_unit_cpu == NR_CPUS) |
430 |
+- pcpu_first_unit_cpu = cpu; |
431 |
+- pcpu_last_unit_cpu = cpu; |
432 |
++ /* determine low/high unit_cpu */ |
433 |
++ if (pcpu_low_unit_cpu == NR_CPUS || |
434 |
++ unit_off[cpu] < unit_off[pcpu_low_unit_cpu]) |
435 |
++ pcpu_low_unit_cpu = cpu; |
436 |
++ if (pcpu_high_unit_cpu == NR_CPUS || |
437 |
++ unit_off[cpu] > unit_off[pcpu_high_unit_cpu]) |
438 |
++ pcpu_high_unit_cpu = cpu; |
439 |
+ } |
440 |
+ } |
441 |
+ pcpu_nr_units = unit; |
442 |
+diff --git a/mm/util.c b/mm/util.c |
443 |
+index b377ce4..e48b493 100644 |
444 |
+--- a/mm/util.c |
445 |
++++ b/mm/util.c |
446 |
+@@ -233,6 +233,19 @@ void arch_pick_mmap_layout(struct mm_struct *mm) |
447 |
+ } |
448 |
+ #endif |
449 |
+ |
450 |
++/* |
451 |
++ * Like get_user_pages_fast() except its IRQ-safe in that it won't fall |
452 |
++ * back to the regular GUP. |
453 |
++ * If the architecture not support this fucntion, simply return with no |
454 |
++ * page pinned |
455 |
++ */ |
456 |
++int __attribute__((weak)) __get_user_pages_fast(unsigned long start, |
457 |
++ int nr_pages, int write, struct page **pages) |
458 |
++{ |
459 |
++ return 0; |
460 |
++} |
461 |
++EXPORT_SYMBOL_GPL(__get_user_pages_fast); |
462 |
++ |
463 |
+ /** |
464 |
+ * get_user_pages_fast() - pin user pages in memory |
465 |
+ * @start: starting user address |
466 |
+diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c |
467 |
+index faf54c6..9bd850a 100644 |
468 |
+--- a/net/xfrm/xfrm_algo.c |
469 |
++++ b/net/xfrm/xfrm_algo.c |
470 |
+@@ -411,8 +411,8 @@ static struct xfrm_algo_desc ealg_list[] = { |
471 |
+ .desc = { |
472 |
+ .sadb_alg_id = SADB_X_EALG_AESCTR, |
473 |
+ .sadb_alg_ivlen = 8, |
474 |
+- .sadb_alg_minbits = 128, |
475 |
+- .sadb_alg_maxbits = 256 |
476 |
++ .sadb_alg_minbits = 160, |
477 |
++ .sadb_alg_maxbits = 288 |
478 |
+ } |
479 |
+ }, |
480 |
+ }; |
481 |
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c |
482 |
+index ba44dc0..6419095 100644 |
483 |
+--- a/sound/pci/hda/patch_realtek.c |
484 |
++++ b/sound/pci/hda/patch_realtek.c |
485 |
+@@ -432,6 +432,8 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, |
486 |
+ imux = &spec->input_mux[mux_idx]; |
487 |
+ if (!imux->num_items && mux_idx > 0) |
488 |
+ imux = &spec->input_mux[0]; |
489 |
++ if (!imux->num_items) |
490 |
++ return 0; |
491 |
+ |
492 |
+ type = get_wcaps_type(get_wcaps(codec, nid)); |
493 |
+ if (type == AC_WID_AUD_MIX) { |
494 |
+diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c |
495 |
+index 1a5ff06..b11ee62 100644 |
496 |
+--- a/sound/pci/sis7019.c |
497 |
++++ b/sound/pci/sis7019.c |
498 |
+@@ -40,6 +40,7 @@ MODULE_SUPPORTED_DEVICE("{{SiS,SiS7019 Audio Accelerator}}"); |
499 |
+ static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ |
500 |
+ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ |
501 |
+ static int enable = 1; |
502 |
++static int codecs = 1; |
503 |
+ |
504 |
+ module_param(index, int, 0444); |
505 |
+ MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator."); |
506 |
+@@ -47,6 +48,8 @@ module_param(id, charp, 0444); |
507 |
+ MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator."); |
508 |
+ module_param(enable, bool, 0444); |
509 |
+ MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator."); |
510 |
++module_param(codecs, int, 0444); |
511 |
++MODULE_PARM_DESC(codecs, "Set bit to indicate that codec number is expected to be present (default 1)"); |
512 |
+ |
513 |
+ static struct pci_device_id snd_sis7019_ids[] = { |
514 |
+ { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) }, |
515 |
+@@ -139,6 +142,9 @@ struct sis7019 { |
516 |
+ dma_addr_t silence_dma_addr; |
517 |
+ }; |
518 |
+ |
519 |
++/* These values are also used by the module param 'codecs' to indicate |
520 |
++ * which codecs should be present. |
521 |
++ */ |
522 |
+ #define SIS_PRIMARY_CODEC_PRESENT 0x0001 |
523 |
+ #define SIS_SECONDARY_CODEC_PRESENT 0x0002 |
524 |
+ #define SIS_TERTIARY_CODEC_PRESENT 0x0004 |
525 |
+@@ -1075,6 +1081,7 @@ static int sis_chip_init(struct sis7019 *sis) |
526 |
+ { |
527 |
+ unsigned long io = sis->ioport; |
528 |
+ void __iomem *ioaddr = sis->ioaddr; |
529 |
++ unsigned long timeout; |
530 |
+ u16 status; |
531 |
+ int count; |
532 |
+ int i; |
533 |
+@@ -1101,21 +1108,45 @@ static int sis_chip_init(struct sis7019 *sis) |
534 |
+ while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count) |
535 |
+ udelay(1); |
536 |
+ |
537 |
++ /* Command complete, we can let go of the semaphore now. |
538 |
++ */ |
539 |
++ outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA); |
540 |
++ if (!count) |
541 |
++ return -EIO; |
542 |
++ |
543 |
+ /* Now that we've finished the reset, find out what's attached. |
544 |
++ * There are some codec/board combinations that take an extremely |
545 |
++ * long time to come up. 350+ ms has been observed in the field, |
546 |
++ * so we'll give them up to 500ms. |
547 |
+ */ |
548 |
+- status = inl(io + SIS_AC97_STATUS); |
549 |
+- if (status & SIS_AC97_STATUS_CODEC_READY) |
550 |
+- sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT; |
551 |
+- if (status & SIS_AC97_STATUS_CODEC2_READY) |
552 |
+- sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT; |
553 |
+- if (status & SIS_AC97_STATUS_CODEC3_READY) |
554 |
+- sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT; |
555 |
+- |
556 |
+- /* All done, let go of the semaphore, and check for errors |
557 |
++ sis->codecs_present = 0; |
558 |
++ timeout = msecs_to_jiffies(500) + jiffies; |
559 |
++ while (time_before_eq(jiffies, timeout)) { |
560 |
++ status = inl(io + SIS_AC97_STATUS); |
561 |
++ if (status & SIS_AC97_STATUS_CODEC_READY) |
562 |
++ sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT; |
563 |
++ if (status & SIS_AC97_STATUS_CODEC2_READY) |
564 |
++ sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT; |
565 |
++ if (status & SIS_AC97_STATUS_CODEC3_READY) |
566 |
++ sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT; |
567 |
++ |
568 |
++ if (sis->codecs_present == codecs) |
569 |
++ break; |
570 |
++ |
571 |
++ msleep(1); |
572 |
++ } |
573 |
++ |
574 |
++ /* All done, check for errors. |
575 |
+ */ |
576 |
+- outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA); |
577 |
+- if (!sis->codecs_present || !count) |
578 |
++ if (!sis->codecs_present) { |
579 |
++ printk(KERN_ERR "sis7019: could not find any codecs\n"); |
580 |
+ return -EIO; |
581 |
++ } |
582 |
++ |
583 |
++ if (sis->codecs_present != codecs) { |
584 |
++ printk(KERN_WARNING "sis7019: missing codecs, found %0x, expected %0x\n", |
585 |
++ sis->codecs_present, codecs); |
586 |
++ } |
587 |
+ |
588 |
+ /* Let the hardware know that the audio driver is alive, |
589 |
+ * and enable PCM slots on the AC-link for L/R playback (3 & 4) and |
590 |
+@@ -1387,6 +1418,17 @@ static int __devinit snd_sis7019_probe(struct pci_dev *pci, |
591 |
+ if (!enable) |
592 |
+ goto error_out; |
593 |
+ |
594 |
++ /* The user can specify which codecs should be present so that we |
595 |
++ * can wait for them to show up if they are slow to recover from |
596 |
++ * the AC97 cold reset. We default to a single codec, the primary. |
597 |
++ * |
598 |
++ * We assume that SIS_PRIMARY_*_PRESENT matches bits 0-2. |
599 |
++ */ |
600 |
++ codecs &= SIS_PRIMARY_CODEC_PRESENT | SIS_SECONDARY_CODEC_PRESENT | |
601 |
++ SIS_TERTIARY_CODEC_PRESENT; |
602 |
++ if (!codecs) |
603 |
++ codecs = SIS_PRIMARY_CODEC_PRESENT; |
604 |
++ |
605 |
+ rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card); |
606 |
+ if (rc < 0) |
607 |
+ goto error_out; |