Magellan Linux

Contents of /trunk/kernel26-alx/patches-2.6.20-r6/0121-2.6.20.21-all-fixes.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1175 - (show annotations) (download)
Thu Oct 14 12:15:46 2010 UTC (13 years, 6 months ago) by niro
File size: 36574 byte(s)
-2.6.20-alx-r6 new magellan 0.5.2 kernel
1 diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c
2 index 666f70d..0577312 100644
3 --- a/arch/i386/kernel/sysenter.c
4 +++ b/arch/i386/kernel/sysenter.c
5 @@ -183,7 +183,9 @@ struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
6
7 int in_gate_area(struct task_struct *task, unsigned long addr)
8 {
9 - return 0;
10 + const struct vm_area_struct *vma = get_gate_vma(task);
11 +
12 + return vma && addr >= vma->vm_start && addr < vma->vm_end;
13 }
14
15 int in_gate_area_no_task(unsigned long addr)
16 diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
17 index f3d4dd5..21d4caf 100644
18 --- a/arch/powerpc/kernel/process.c
19 +++ b/arch/powerpc/kernel/process.c
20 @@ -84,7 +84,7 @@ void flush_fp_to_thread(struct task_struct *tsk)
21 */
22 BUG_ON(tsk != current);
23 #endif
24 - giveup_fpu(current);
25 + giveup_fpu(tsk);
26 }
27 preempt_enable();
28 }
29 @@ -144,7 +144,7 @@ void flush_altivec_to_thread(struct task_struct *tsk)
30 #ifdef CONFIG_SMP
31 BUG_ON(tsk != current);
32 #endif
33 - giveup_altivec(current);
34 + giveup_altivec(tsk);
35 }
36 preempt_enable();
37 }
38 @@ -183,7 +183,7 @@ void flush_spe_to_thread(struct task_struct *tsk)
39 #ifdef CONFIG_SMP
40 BUG_ON(tsk != current);
41 #endif
42 - giveup_spe(current);
43 + giveup_spe(tsk);
44 }
45 preempt_enable();
46 }
47 diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
48 index ad67784..ab72e91 100644
49 --- a/arch/sparc64/kernel/traps.c
50 +++ b/arch/sparc64/kernel/traps.c
51 @@ -2146,12 +2146,20 @@ static void user_instruction_dump (unsigned int __user *pc)
52 void show_stack(struct task_struct *tsk, unsigned long *_ksp)
53 {
54 unsigned long pc, fp, thread_base, ksp;
55 - void *tp = task_stack_page(tsk);
56 + struct thread_info *tp;
57 struct reg_window *rw;
58 int count = 0;
59
60 ksp = (unsigned long) _ksp;
61 -
62 + if (!tsk)
63 + tsk = current;
64 + tp = task_thread_info(tsk);
65 + if (ksp == 0UL) {
66 + if (tsk == current)
67 + asm("mov %%fp, %0" : "=r" (ksp));
68 + else
69 + ksp = tp->ksp;
70 + }
71 if (tp == current_thread_info())
72 flushw_all();
73
74 @@ -2180,11 +2188,7 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp)
75
76 void dump_stack(void)
77 {
78 - unsigned long *ksp;
79 -
80 - __asm__ __volatile__("mov %%fp, %0"
81 - : "=r" (ksp));
82 - show_stack(current, ksp);
83 + show_stack(current, NULL);
84 }
85
86 EXPORT_SYMBOL(dump_stack);
87 diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
88 index 55ae802..f6377b4 100644
89 --- a/arch/sparc64/mm/fault.c
90 +++ b/arch/sparc64/mm/fault.c
91 @@ -129,15 +129,12 @@ static void __kprobes unhandled_fault(unsigned long address,
92
93 static void bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr)
94 {
95 - unsigned long *ksp;
96 -
97 printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n",
98 regs->tpc);
99 printk(KERN_CRIT "OOPS: RPC [%016lx]\n", regs->u_regs[15]);
100 print_symbol("RPC: <%s>\n", regs->u_regs[15]);
101 printk(KERN_CRIT "OOPS: Fault was to vaddr[%lx]\n", vaddr);
102 - __asm__("mov %%sp, %0" : "=r" (ksp));
103 - show_stack(current, ksp);
104 + dump_stack();
105 unhandled_fault(regs->tpc, current, regs);
106 }
107
108 diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
109 index 38c293b..dbb0192 100644
110 --- a/block/ll_rw_blk.c
111 +++ b/block/ll_rw_blk.c
112 @@ -1072,12 +1072,6 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq)
113 */
114 return;
115
116 - if (unlikely(!__test_and_clear_bit(tag, bqt->tag_map))) {
117 - printk(KERN_ERR "%s: attempt to clear non-busy tag (%d)\n",
118 - __FUNCTION__, tag);
119 - return;
120 - }
121 -
122 list_del_init(&rq->queuelist);
123 rq->cmd_flags &= ~REQ_QUEUED;
124 rq->tag = -1;
125 @@ -1087,6 +1081,13 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq)
126 __FUNCTION__, tag);
127
128 bqt->tag_index[tag] = NULL;
129 +
130 + if (unlikely(!test_and_clear_bit(tag, bqt->tag_map))) {
131 + printk(KERN_ERR "%s: attempt to clear non-busy tag (%d)\n",
132 + __FUNCTION__, tag);
133 + return;
134 + }
135 +
136 bqt->busy--;
137 }
138
139 diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
140 index 6e93004..cb95fa8 100644
141 --- a/crypto/blkcipher.c
142 +++ b/crypto/blkcipher.c
143 @@ -58,11 +58,13 @@ static inline void blkcipher_unmap_dst(struct blkcipher_walk *walk)
144 scatterwalk_unmap(walk->dst.virt.addr, 1);
145 }
146
147 +/* Get a spot of the specified length that does not straddle a page.
148 + * The caller needs to ensure that there is enough space for this operation.
149 + */
150 static inline u8 *blkcipher_get_spot(u8 *start, unsigned int len)
151 {
152 - if (offset_in_page(start + len) < len)
153 - return (u8 *)((unsigned long)(start + len) & PAGE_MASK);
154 - return start;
155 + u8 *end_page = (u8 *)(((unsigned long)(start + len - 1)) & PAGE_MASK);
156 + return start > end_page ? start : end_page;
157 }
158
159 static inline unsigned int blkcipher_done_slow(struct crypto_blkcipher *tfm,
160 @@ -154,7 +156,8 @@ static inline int blkcipher_next_slow(struct blkcipher_desc *desc,
161 if (walk->buffer)
162 goto ok;
163
164 - n = bsize * 2 + (alignmask & ~(crypto_tfm_ctx_alignment() - 1));
165 + n = bsize * 3 - (alignmask + 1) +
166 + (alignmask & ~(crypto_tfm_ctx_alignment() - 1));
167 walk->buffer = kmalloc(n, GFP_ATOMIC);
168 if (!walk->buffer)
169 return blkcipher_walk_done(desc, walk, -ENOMEM);
170 diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
171 index 95ddeb4..2ae48c2 100644
172 --- a/drivers/acpi/events/evgpeblk.c
173 +++ b/drivers/acpi/events/evgpeblk.c
174 @@ -586,6 +586,10 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt)
175 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
176 if (gpe_xrupt->previous) {
177 gpe_xrupt->previous->next = gpe_xrupt->next;
178 + } else {
179 + /* No previous, update list head */
180 +
181 + acpi_gbl_gpe_xrupt_list_head = gpe_xrupt->next;
182 }
183
184 if (gpe_xrupt->next) {
185 diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
186 index 9a48ca2..3fc3895 100644
187 --- a/drivers/ieee1394/ieee1394_core.c
188 +++ b/drivers/ieee1394/ieee1394_core.c
189 @@ -1170,7 +1170,7 @@ static void __exit ieee1394_cleanup(void)
190 unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
191 }
192
193 -fs_initcall(ieee1394_init); /* same as ohci1394 */
194 +module_init(ieee1394_init);
195 module_exit(ieee1394_cleanup);
196
197 /* Exported symbols */
198 diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
199 index 628130a..ec301a8 100644
200 --- a/drivers/ieee1394/ohci1394.c
201 +++ b/drivers/ieee1394/ohci1394.c
202 @@ -3785,7 +3785,5 @@ static int __init ohci1394_init(void)
203 return pci_register_driver(&ohci1394_pci_driver);
204 }
205
206 -/* Register before most other device drivers.
207 - * Useful for remote debugging via physical DMA, e.g. using firescope. */
208 -fs_initcall(ohci1394_init);
209 +module_init(ohci1394_init);
210 module_exit(ohci1394_cleanup);
211 diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
212 index 1fe1a83..1093ff4 100644
213 --- a/drivers/media/video/cx88/cx88-mpeg.c
214 +++ b/drivers/media/video/cx88/cx88-mpeg.c
215 @@ -556,7 +556,7 @@ struct cx8802_dev * cx8802_get_device(struct inode *inode)
216
217 list_for_each(list,&cx8802_devlist) {
218 h = list_entry(list, struct cx8802_dev, devlist);
219 - if (h->mpeg_dev->minor == minor)
220 + if (h->mpeg_dev && h->mpeg_dev->minor == minor)
221 return h;
222 }
223
224 diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
225 index a996aad..957694a 100644
226 --- a/drivers/media/video/pwc/pwc-if.c
227 +++ b/drivers/media/video/pwc/pwc-if.c
228 @@ -1196,12 +1196,19 @@ static int pwc_video_open(struct inode *inode, struct file *file)
229 return 0;
230 }
231
232 +
233 +static void pwc_cleanup(struct pwc_device *pdev)
234 +{
235 + pwc_remove_sysfs_files(pdev->vdev);
236 + video_unregister_device(pdev->vdev);
237 +}
238 +
239 /* Note that all cleanup is done in the reverse order as in _open */
240 static int pwc_video_close(struct inode *inode, struct file *file)
241 {
242 struct video_device *vdev = file->private_data;
243 struct pwc_device *pdev;
244 - int i;
245 + int i, hint;
246
247 PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
248
249 @@ -1224,8 +1231,9 @@ static int pwc_video_close(struct inode *inode, struct file *file)
250 pwc_isoc_cleanup(pdev);
251 pwc_free_buffers(pdev);
252
253 + lock_kernel();
254 /* Turn off LEDS and power down camera, but only when not unplugged */
255 - if (pdev->error_status != EPIPE) {
256 + if (!pdev->unplugged) {
257 /* Turn LEDs off */
258 if (pwc_set_leds(pdev, 0, 0) < 0)
259 PWC_DEBUG_MODULE("Failed to set LED on/off time.\n");
260 @@ -1234,9 +1242,19 @@ static int pwc_video_close(struct inode *inode, struct file *file)
261 if (i < 0)
262 PWC_ERROR("Failed to power down camera (%d)\n", i);
263 }
264 + pdev->vopen--;
265 + PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", i);
266 + } else {
267 + pwc_cleanup(pdev);
268 + /* Free memory (don't set pdev to 0 just yet) */
269 + kfree(pdev);
270 + /* search device_hint[] table if we occupy a slot, by any chance */
271 + for (hint = 0; hint < MAX_DEV_HINTS; hint++)
272 + if (device_hint[hint].pdev == pdev)
273 + device_hint[hint].pdev = NULL;
274 }
275 - pdev->vopen--;
276 - PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen);
277 + unlock_kernel();
278 +
279 return 0;
280 }
281
282 @@ -1783,21 +1801,21 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
283 /* Alert waiting processes */
284 wake_up_interruptible(&pdev->frameq);
285 /* Wait until device is closed */
286 - while (pdev->vopen)
287 - schedule();
288 - /* Device is now closed, so we can safely unregister it */
289 - PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
290 - pwc_remove_sysfs_files(pdev->vdev);
291 - video_unregister_device(pdev->vdev);
292 -
293 - /* Free memory (don't set pdev to 0 just yet) */
294 - kfree(pdev);
295 + if(pdev->vopen) {
296 + pdev->unplugged = 1;
297 + } else {
298 + /* Device is closed, so we can safely unregister it */
299 + PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
300 + pwc_cleanup(pdev);
301 + /* Free memory (don't set pdev to 0 just yet) */
302 + kfree(pdev);
303
304 disconnect_out:
305 - /* search device_hint[] table if we occupy a slot, by any chance */
306 - for (hint = 0; hint < MAX_DEV_HINTS; hint++)
307 - if (device_hint[hint].pdev == pdev)
308 - device_hint[hint].pdev = NULL;
309 + /* search device_hint[] table if we occupy a slot, by any chance */
310 + for (hint = 0; hint < MAX_DEV_HINTS; hint++)
311 + if (device_hint[hint].pdev == pdev)
312 + device_hint[hint].pdev = NULL;
313 + }
314
315 unlock_kernel();
316 }
317 diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
318 index 7e9c423..7dae6c4 100644
319 --- a/drivers/media/video/pwc/pwc.h
320 +++ b/drivers/media/video/pwc/pwc.h
321 @@ -198,6 +198,7 @@ struct pwc_device
322 char vsnapshot; /* snapshot mode */
323 char vsync; /* used by isoc handler */
324 char vmirror; /* for ToUCaM series */
325 + char unplugged;
326
327 int cmd_len;
328 unsigned char cmd_buf[13];
329 diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
330 index c383dc3..f18edd8 100644
331 --- a/drivers/net/forcedeth.c
332 +++ b/drivers/net/forcedeth.c
333 @@ -554,6 +554,7 @@ union ring_type {
334 #define PHY_OUI_MARVELL 0x5043
335 #define PHY_OUI_CICADA 0x03f1
336 #define PHY_OUI_VITESSE 0x01c1
337 +#define PHY_OUI_REALTEK 0x0732
338 #define PHYID1_OUI_MASK 0x03ff
339 #define PHYID1_OUI_SHFT 6
340 #define PHYID2_OUI_MASK 0xfc00
341 diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
342 index 1aafa71..2847a0c 100644
343 --- a/drivers/net/r8169.c
344 +++ b/drivers/net/r8169.c
345 @@ -2646,14 +2646,16 @@ rtl8169_interrupt(int irq, void *dev_instance)
346 rtl8169_check_link_status(dev, tp, ioaddr);
347
348 #ifdef CONFIG_R8169_NAPI
349 - RTL_W16(IntrMask, rtl8169_intr_mask & ~rtl8169_napi_event);
350 - tp->intr_mask = ~rtl8169_napi_event;
351 -
352 - if (likely(netif_rx_schedule_prep(dev)))
353 - __netif_rx_schedule(dev);
354 - else if (netif_msg_intr(tp)) {
355 - printk(KERN_INFO "%s: interrupt %04x taken in poll\n",
356 - dev->name, status);
357 + if (status & rtl8169_napi_event) {
358 + RTL_W16(IntrMask, rtl8169_intr_mask & ~rtl8169_napi_event);
359 + tp->intr_mask = ~rtl8169_napi_event;
360 +
361 + if (likely(netif_rx_schedule_prep(dev)))
362 + __netif_rx_schedule(dev);
363 + else if (netif_msg_intr(tp)) {
364 + printk(KERN_INFO "%s: interrupt %04x in poll\n",
365 + dev->name, status);
366 + }
367 }
368 break;
369 #else
370 diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
371 index b091a0f..9040564 100644
372 --- a/drivers/scsi/3w-9xxx.c
373 +++ b/drivers/scsi/3w-9xxx.c
374 @@ -4,7 +4,7 @@
375 Written By: Adam Radford <linuxraid@amcc.com>
376 Modifications By: Tom Couch <linuxraid@amcc.com>
377
378 - Copyright (C) 2004-2006 Applied Micro Circuits Corporation.
379 + Copyright (C) 2004-2007 Applied Micro Circuits Corporation.
380
381 This program is free software; you can redistribute it and/or modify
382 it under the terms of the GNU General Public License as published by
383 @@ -69,6 +69,7 @@
384 2.26.02.008 - Free irq handler in __twa_shutdown().
385 Serialize reset code.
386 Add support for 9650SE controllers.
387 + 2.26.02.009 - Fix dma mask setting to fallback to 32-bit if 64-bit fails.
388 */
389
390 #include <linux/module.h>
391 @@ -92,7 +93,7 @@
392 #include "3w-9xxx.h"
393
394 /* Globals */
395 -#define TW_DRIVER_VERSION "2.26.02.008"
396 +#define TW_DRIVER_VERSION "2.26.02.009"
397 static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
398 static unsigned int twa_device_extension_count;
399 static int twa_major = -1;
400 @@ -2063,11 +2064,14 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id
401
402 pci_set_master(pdev);
403
404 - retval = pci_set_dma_mask(pdev, sizeof(dma_addr_t) > 4 ? DMA_64BIT_MASK : DMA_32BIT_MASK);
405 - if (retval) {
406 - TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask");
407 - goto out_disable_device;
408 - }
409 + if (pci_set_dma_mask(pdev, DMA_64BIT_MASK)
410 + || pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
411 + if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)
412 + || pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
413 + TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask");
414 + retval = -ENODEV;
415 + goto out_disable_device;
416 + }
417
418 host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
419 if (!host) {
420 diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
421 index d6eb5ce..c5dc61a 100644
422 --- a/drivers/usb/core/driver.c
423 +++ b/drivers/usb/core/driver.c
424 @@ -66,7 +66,7 @@ static ssize_t store_new_id(struct device_driver *driver,
425 dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE;
426
427 spin_lock(&usb_drv->dynids.lock);
428 - list_add_tail(&usb_drv->dynids.list, &dynid->node);
429 + list_add_tail(&dynid->node, &usb_drv->dynids.list);
430 spin_unlock(&usb_drv->dynids.lock);
431
432 if (get_driver(driver)) {
433 diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
434 index 149aa8b..dec1337 100644
435 --- a/drivers/usb/core/message.c
436 +++ b/drivers/usb/core/message.c
437 @@ -608,12 +608,12 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char
438 memset(buf,0,size); // Make sure we parse really received data
439
440 for (i = 0; i < 3; ++i) {
441 - /* retry on length 0 or stall; some devices are flakey */
442 + /* retry on length 0 or error; some devices are flakey */
443 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
444 USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
445 (type << 8) + index, 0, buf, size,
446 USB_CTRL_GET_TIMEOUT);
447 - if (result == 0 || result == -EPIPE)
448 + if (result <= 0 && result != -ETIMEDOUT)
449 continue;
450 if (result > 1 && ((u8 *)buf)[1] != type) {
451 result = -EPROTO;
452 diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
453 index 4df39c4..99f0f72 100644
454 --- a/fs/ext3/namei.c
455 +++ b/fs/ext3/namei.c
456 @@ -380,13 +380,28 @@ dx_probe(struct dentry *dentry, struct inode *dir,
457
458 entries = (struct dx_entry *) (((char *)&root->info) +
459 root->info.info_length);
460 - assert(dx_get_limit(entries) == dx_root_limit(dir,
461 - root->info.info_length));
462 +
463 + if (dx_get_limit(entries) != dx_root_limit(dir,
464 + root->info.info_length)) {
465 + ext3_warning(dir->i_sb, __FUNCTION__,
466 + "dx entry: limit != root limit");
467 + brelse(bh);
468 + *err = ERR_BAD_DX_DIR;
469 + goto fail;
470 + }
471 +
472 dxtrace (printk("Look up %x", hash));
473 while (1)
474 {
475 count = dx_get_count(entries);
476 - assert (count && count <= dx_get_limit(entries));
477 + if (!count || count > dx_get_limit(entries)) {
478 + ext3_warning(dir->i_sb, __FUNCTION__,
479 + "dx entry: no count or count > limit");
480 + brelse(bh);
481 + *err = ERR_BAD_DX_DIR;
482 + goto fail2;
483 + }
484 +
485 p = entries + 1;
486 q = entries + count - 1;
487 while (p <= q)
488 @@ -424,8 +439,15 @@ dx_probe(struct dentry *dentry, struct inode *dir,
489 if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err)))
490 goto fail2;
491 at = entries = ((struct dx_node *) bh->b_data)->entries;
492 - assert (dx_get_limit(entries) == dx_node_limit (dir));
493 + if (dx_get_limit(entries) != dx_node_limit (dir)) {
494 + ext3_warning(dir->i_sb, __FUNCTION__,
495 + "dx entry: limit != node limit");
496 + brelse(bh);
497 + *err = ERR_BAD_DX_DIR;
498 + goto fail2;
499 + }
500 frame++;
501 + frame->bh = NULL;
502 }
503 fail2:
504 while (frame >= frame_in) {
505 @@ -433,6 +455,10 @@ fail2:
506 frame--;
507 }
508 fail:
509 + if (*err == ERR_BAD_DX_DIR)
510 + ext3_warning(dir->i_sb, __FUNCTION__,
511 + "Corrupt dir inode %ld, running e2fsck is "
512 + "recommended.", dir->i_ino);
513 return NULL;
514 }
515
516 diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
517 index e5a74a5..5edc327 100644
518 --- a/fs/ext4/namei.c
519 +++ b/fs/ext4/namei.c
520 @@ -380,13 +380,28 @@ dx_probe(struct dentry *dentry, struct inode *dir,
521
522 entries = (struct dx_entry *) (((char *)&root->info) +
523 root->info.info_length);
524 - assert(dx_get_limit(entries) == dx_root_limit(dir,
525 - root->info.info_length));
526 +
527 + if (dx_get_limit(entries) != dx_root_limit(dir,
528 + root->info.info_length)) {
529 + ext4_warning(dir->i_sb, __FUNCTION__,
530 + "dx entry: limit != root limit");
531 + brelse(bh);
532 + *err = ERR_BAD_DX_DIR;
533 + goto fail;
534 + }
535 +
536 dxtrace (printk("Look up %x", hash));
537 while (1)
538 {
539 count = dx_get_count(entries);
540 - assert (count && count <= dx_get_limit(entries));
541 + if (!count || count > dx_get_limit(entries)) {
542 + ext4_warning(dir->i_sb, __FUNCTION__,
543 + "dx entry: no count or count > limit");
544 + brelse(bh);
545 + *err = ERR_BAD_DX_DIR;
546 + goto fail2;
547 + }
548 +
549 p = entries + 1;
550 q = entries + count - 1;
551 while (p <= q)
552 @@ -424,8 +439,15 @@ dx_probe(struct dentry *dentry, struct inode *dir,
553 if (!(bh = ext4_bread (NULL,dir, dx_get_block(at), 0, err)))
554 goto fail2;
555 at = entries = ((struct dx_node *) bh->b_data)->entries;
556 - assert (dx_get_limit(entries) == dx_node_limit (dir));
557 + if (dx_get_limit(entries) != dx_node_limit (dir)) {
558 + ext4_warning(dir->i_sb, __FUNCTION__,
559 + "dx entry: limit != node limit");
560 + brelse(bh);
561 + *err = ERR_BAD_DX_DIR;
562 + goto fail2;
563 + }
564 frame++;
565 + frame->bh = NULL;
566 }
567 fail2:
568 while (frame >= frame_in) {
569 @@ -433,6 +455,10 @@ fail2:
570 frame--;
571 }
572 fail:
573 + if (*err == ERR_BAD_DX_DIR)
574 + ext4_warning(dir->i_sb, __FUNCTION__,
575 + "Corrupt dir inode %ld, running e2fsck is "
576 + "recommended.", dir->i_ino);
577 return NULL;
578 }
579
580 diff --git a/fs/locks.c b/fs/locks.c
581 index 52a8100..bcdfebc 100644
582 --- a/fs/locks.c
583 +++ b/fs/locks.c
584 @@ -790,7 +790,7 @@ find_conflict:
585 if (request->fl_flags & FL_ACCESS)
586 goto out;
587 locks_copy_lock(new_fl, request);
588 - locks_insert_lock(&inode->i_flock, new_fl);
589 + locks_insert_lock(before, new_fl);
590 new_fl = NULL;
591 error = 0;
592
593 diff --git a/fs/nfs/super.c b/fs/nfs/super.c
594 index 28108c8..c81fcd8 100644
595 --- a/fs/nfs/super.c
596 +++ b/fs/nfs/super.c
597 @@ -180,8 +180,8 @@ void __exit unregister_nfs_fs(void)
598 remove_shrinker(acl_shrinker);
599 #ifdef CONFIG_NFS_V4
600 unregister_filesystem(&nfs4_fs_type);
601 - nfs_unregister_sysctl();
602 #endif
603 + nfs_unregister_sysctl();
604 unregister_filesystem(&nfs_fs_type);
605 }
606
607 diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
608 index 511edef..3743086 100644
609 --- a/fs/sysfs/dir.c
610 +++ b/fs/sysfs/dir.c
611 @@ -29,6 +29,14 @@ static struct dentry_operations sysfs_dentry_ops = {
612 .d_iput = sysfs_d_iput,
613 };
614
615 +static unsigned int sysfs_inode_counter;
616 +ino_t sysfs_get_inum(void)
617 +{
618 + if (unlikely(sysfs_inode_counter < 3))
619 + sysfs_inode_counter = 3;
620 + return sysfs_inode_counter++;
621 +}
622 +
623 /*
624 * Allocates a new sysfs_dirent and links it to the parent sysfs_dirent
625 */
626 @@ -42,6 +50,7 @@ static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent * parent_sd,
627 return NULL;
628
629 memset(sd, 0, sizeof(*sd));
630 + sd->s_ino = sysfs_get_inum();
631 atomic_set(&sd->s_count, 1);
632 atomic_set(&sd->s_event, 1);
633 INIT_LIST_HEAD(&sd->s_children);
634 @@ -461,7 +470,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
635
636 switch (i) {
637 case 0:
638 - ino = dentry->d_inode->i_ino;
639 + ino = parent_sd->s_ino;
640 if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
641 break;
642 filp->f_pos++;
643 @@ -490,10 +499,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
644
645 name = sysfs_get_name(next);
646 len = strlen(name);
647 - if (next->s_dentry)
648 - ino = next->s_dentry->d_inode->i_ino;
649 - else
650 - ino = iunique(sysfs_sb, 2);
651 + ino = next->s_ino;
652
653 if (filldir(dirent, name, len, filp->f_pos, ino,
654 dt_type(next)) < 0)
655 diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
656 index e79e38d..bb2da9d 100644
657 --- a/fs/sysfs/inode.c
658 +++ b/fs/sysfs/inode.c
659 @@ -129,6 +129,7 @@ struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent * sd)
660 inode->i_mapping->a_ops = &sysfs_aops;
661 inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
662 inode->i_op = &sysfs_inode_operations;
663 + inode->i_ino = sd->s_ino;
664 lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key);
665
666 if (sd->s_iattr) {
667 diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
668 index e503f85..4305e46 100644
669 --- a/fs/sysfs/mount.c
670 +++ b/fs/sysfs/mount.c
671 @@ -29,6 +29,7 @@ static struct sysfs_dirent sysfs_root = {
672 .s_element = NULL,
673 .s_type = SYSFS_ROOT,
674 .s_iattr = NULL,
675 + .s_ino = 1,
676 };
677
678 static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
679 diff --git a/include/asm-avr32/atomic.h b/include/asm-avr32/atomic.h
680 index c40b603..7df7b75 100644
681 --- a/include/asm-avr32/atomic.h
682 +++ b/include/asm-avr32/atomic.h
683 @@ -101,7 +101,7 @@ static inline int atomic_sub_unless(atomic_t *v, int a, int u)
684 " mov %1, 1\n"
685 "1:"
686 : "=&r"(tmp), "=&r"(result), "=o"(v->counter)
687 - : "m"(v->counter), "rKs21"(a), "rKs21"(u)
688 + : "m"(v->counter), "rKs21"(a), "rKs21"(u), "1"(result)
689 : "cc", "memory");
690
691 return result;
692 @@ -137,7 +137,7 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
693 " mov %1, 1\n"
694 "1:"
695 : "=&r"(tmp), "=&r"(result), "=o"(v->counter)
696 - : "m"(v->counter), "r"(a), "ir"(u)
697 + : "m"(v->counter), "r"(a), "ir"(u), "1"(result)
698 : "cc", "memory");
699 }
700
701 diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild
702 index 6328175..ab399fc 100644
703 --- a/include/linux/netfilter/Kbuild
704 +++ b/include/linux/netfilter/Kbuild
705 @@ -28,6 +28,7 @@ header-y += xt_policy.h
706 header-y += xt_realm.h
707 header-y += xt_sctp.h
708 header-y += xt_state.h
709 +header-y += xt_statistic.h
710 header-y += xt_string.h
711 header-y += xt_tcpmss.h
712 header-y += xt_tcpudp.h
713 diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
714 index 2129d1b..8799dc3 100644
715 --- a/include/linux/sysfs.h
716 +++ b/include/linux/sysfs.h
717 @@ -73,6 +73,7 @@ struct sysfs_dirent {
718 void * s_element;
719 int s_type;
720 umode_t s_mode;
721 + ino_t s_ino;
722 struct dentry * s_dentry;
723 struct iattr * s_iattr;
724 atomic_t s_event;
725 diff --git a/include/net/tcp.h b/include/net/tcp.h
726 index cd8fa0c..da5bac3 100644
727 --- a/include/net/tcp.h
728 +++ b/include/net/tcp.h
729 @@ -273,7 +273,7 @@ extern int tcp_v4_remember_stamp(struct sock *sk);
730
731 extern int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw);
732
733 -extern int tcp_sendmsg(struct kiocb *iocb, struct sock *sk,
734 +extern int tcp_sendmsg(struct kiocb *iocb, struct socket *sock,
735 struct msghdr *msg, size_t size);
736 extern ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags);
737
738 diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c
739 index 50f24ee..5f0115f 100644
740 --- a/kernel/futex_compat.c
741 +++ b/kernel/futex_compat.c
742 @@ -61,10 +61,10 @@ void compat_exit_robust_list(struct task_struct *curr)
743 if (fetch_robust_entry(&upending, &pending,
744 &head->list_op_pending, &pip))
745 return;
746 - if (upending)
747 + if (pending)
748 handle_futex_death((void __user *)pending + futex_offset, curr, pip);
749
750 - while (compat_ptr(uentry) != &head->list) {
751 + while (entry != (struct robust_list __user *) &head->list) {
752 /*
753 * A pending lock might already be on the list, so
754 * dont process it twice:
755 diff --git a/kernel/signal.c b/kernel/signal.c
756 index 5630255..4975f4c 100644
757 --- a/kernel/signal.c
758 +++ b/kernel/signal.c
759 @@ -1345,20 +1345,19 @@ struct sigqueue *sigqueue_alloc(void)
760 void sigqueue_free(struct sigqueue *q)
761 {
762 unsigned long flags;
763 + spinlock_t *lock = &current->sighand->siglock;
764 +
765 BUG_ON(!(q->flags & SIGQUEUE_PREALLOC));
766 /*
767 * If the signal is still pending remove it from the
768 - * pending queue.
769 + * pending queue. We must hold ->siglock while testing
770 + * q->list to serialize with collect_signal().
771 */
772 - if (unlikely(!list_empty(&q->list))) {
773 - spinlock_t *lock = &current->sighand->siglock;
774 - read_lock(&tasklist_lock);
775 - spin_lock_irqsave(lock, flags);
776 - if (!list_empty(&q->list))
777 - list_del_init(&q->list);
778 - spin_unlock_irqrestore(lock, flags);
779 - read_unlock(&tasklist_lock);
780 - }
781 + spin_lock_irqsave(lock, flags);
782 + if (!list_empty(&q->list))
783 + list_del_init(&q->list);
784 + spin_unlock_irqrestore(lock, flags);
785 +
786 q->flags &= ~SIGQUEUE_PREALLOC;
787 __sigqueue_free(q);
788 }
789 diff --git a/kernel/sys.c b/kernel/sys.c
790 index 475ddbb..17f8447 100644
791 --- a/kernel/sys.c
792 +++ b/kernel/sys.c
793 @@ -1358,7 +1358,6 @@ asmlinkage long sys_times(struct tms __user * tbuf)
794 * Auch. Had to add the 'did_exec' flag to conform completely to POSIX.
795 * LBT 04.03.94
796 */
797 -
798 asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
799 {
800 struct task_struct *p;
801 @@ -1386,7 +1385,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
802 if (!thread_group_leader(p))
803 goto out;
804
805 - if (p->real_parent == group_leader) {
806 + if (p->real_parent->tgid == group_leader->tgid) {
807 err = -EPERM;
808 if (process_session(p) != process_session(group_leader))
809 goto out;
810 diff --git a/net/802/psnap.c b/net/802/psnap.c
811 index 270b9d2..44dc3f9 100644
812 --- a/net/802/psnap.c
813 +++ b/net/802/psnap.c
814 @@ -55,6 +55,9 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev,
815 .type = __constant_htons(ETH_P_SNAP),
816 };
817
818 + if (unlikely(!pskb_may_pull(skb, 5)))
819 + goto drop;
820 +
821 rcu_read_lock();
822 proto = find_snap_client(skb->h.raw);
823 if (proto) {
824 @@ -62,14 +65,18 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev,
825 skb->h.raw += 5;
826 skb_pull_rcsum(skb, 5);
827 rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev);
828 - } else {
829 - skb->sk = NULL;
830 - kfree_skb(skb);
831 - rc = 1;
832 }
833 -
834 rcu_read_unlock();
835 +
836 + if (unlikely(!proto))
837 + goto drop;
838 +
839 +out:
840 return rc;
841 +
842 +drop:
843 + kfree_skb(skb);
844 + goto out;
845 }
846
847 /*
848 diff --git a/net/core/datagram.c b/net/core/datagram.c
849 index 797fdd4..5d55a2e 100644
850 --- a/net/core/datagram.c
851 +++ b/net/core/datagram.c
852 @@ -444,6 +444,9 @@ int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
853 __wsum csum;
854 int chunk = skb->len - hlen;
855
856 + if (!chunk)
857 + return 0;
858 +
859 /* Skip filled elements.
860 * Pretty silly, look at memcpy_toiovec, though 8)
861 */
862 diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
863 index fd38b05..05324db 100644
864 --- a/net/dccp/ccids/ccid2.c
865 +++ b/net/dccp/ccids/ccid2.c
866 @@ -298,7 +298,7 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
867 int rc;
868
869 ccid2_pr_debug("allocating more space in history\n");
870 - rc = ccid2_hc_tx_alloc_seq(hctx, CCID2_SEQBUF_LEN, GFP_KERNEL);
871 + rc = ccid2_hc_tx_alloc_seq(hctx, CCID2_SEQBUF_LEN, gfp_any());
872 BUG_ON(rc); /* XXX what do we do? */
873
874 next = hctx->ccid2hctx_seqh->ccid2s_next;
875 diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
876 index 8640096..d8e6f77 100644
877 --- a/net/ipv4/af_inet.c
878 +++ b/net/ipv4/af_inet.c
879 @@ -803,7 +803,7 @@ const struct proto_ops inet_stream_ops = {
880 .shutdown = inet_shutdown,
881 .setsockopt = sock_common_setsockopt,
882 .getsockopt = sock_common_getsockopt,
883 - .sendmsg = inet_sendmsg,
884 + .sendmsg = tcp_sendmsg,
885 .recvmsg = sock_common_recvmsg,
886 .mmap = sock_no_mmap,
887 .sendpage = tcp_sendpage,
888 diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
889 index 67a5509..41ad421 100644
890 --- a/net/ipv4/ah4.c
891 +++ b/net/ipv4/ah4.c
892 @@ -46,7 +46,7 @@ static int ip_clear_mutable_options(struct iphdr *iph, __be32 *daddr)
893 memcpy(daddr, optptr+optlen-4, 4);
894 /* Fall through */
895 default:
896 - memset(optptr+2, 0, optlen-2);
897 + memset(optptr, 0, optlen);
898 }
899 l -= optlen;
900 optptr += optlen;
901 diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
902 index 6842474..a3818f2 100644
903 --- a/net/ipv4/tcp.c
904 +++ b/net/ipv4/tcp.c
905 @@ -658,9 +658,10 @@ static inline int select_size(struct sock *sk, struct tcp_sock *tp)
906 return tmp;
907 }
908
909 -int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
910 +int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
911 size_t size)
912 {
913 + struct sock *sk = sock->sk;
914 struct iovec *iov;
915 struct tcp_sock *tp = tcp_sk(sk);
916 struct sk_buff *skb;
917 diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
918 index 12de90a..9c4862f 100644
919 --- a/net/ipv4/tcp_ipv4.c
920 +++ b/net/ipv4/tcp_ipv4.c
921 @@ -2427,7 +2427,6 @@ struct proto tcp_prot = {
922 .shutdown = tcp_shutdown,
923 .setsockopt = tcp_setsockopt,
924 .getsockopt = tcp_getsockopt,
925 - .sendmsg = tcp_sendmsg,
926 .recvmsg = tcp_recvmsg,
927 .backlog_rcv = tcp_v4_do_rcv,
928 .hash = tcp_v4_hash,
929 diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
930 index 0e0e426..30c8299 100644
931 --- a/net/ipv6/af_inet6.c
932 +++ b/net/ipv6/af_inet6.c
933 @@ -473,7 +473,7 @@ const struct proto_ops inet6_stream_ops = {
934 .shutdown = inet_shutdown, /* ok */
935 .setsockopt = sock_common_setsockopt, /* ok */
936 .getsockopt = sock_common_getsockopt, /* ok */
937 - .sendmsg = inet_sendmsg, /* ok */
938 + .sendmsg = tcp_sendmsg, /* ok */
939 .recvmsg = sock_common_recvmsg, /* ok */
940 .mmap = sock_no_mmap,
941 .sendpage = tcp_sendpage,
942 diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
943 index 7b7bd44..2c613fa 100644
944 --- a/net/ipv6/ip6_output.c
945 +++ b/net/ipv6/ip6_output.c
946 @@ -1357,8 +1357,9 @@ void ip6_flush_pending_frames(struct sock *sk)
947 struct sk_buff *skb;
948
949 while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) {
950 - IP6_INC_STATS(ip6_dst_idev(skb->dst),
951 - IPSTATS_MIB_OUTDISCARDS);
952 + if (skb->dst)
953 + IP6_INC_STATS(ip6_dst_idev(skb->dst),
954 + IPSTATS_MIB_OUTDISCARDS);
955 kfree_skb(skb);
956 }
957
958 diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
959 index 9479fbd..ddbe790 100644
960 --- a/net/ipv6/raw.c
961 +++ b/net/ipv6/raw.c
962 @@ -851,11 +851,10 @@ back_from_confirm:
963 ip6_flush_pending_frames(sk);
964 else if (!(msg->msg_flags & MSG_MORE))
965 err = rawv6_push_pending_frames(sk, &fl, rp);
966 + release_sock(sk);
967 }
968 done:
969 dst_release(dst);
970 - if (!inet->hdrincl)
971 - release_sock(sk);
972 out:
973 fl6_sock_release(flowlabel);
974 return err<0?err:len;
975 diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
976 index 03f53f5..f6214b7 100644
977 --- a/net/ipv6/tcp_ipv6.c
978 +++ b/net/ipv6/tcp_ipv6.c
979 @@ -2127,7 +2127,6 @@ struct proto tcpv6_prot = {
980 .shutdown = tcp_shutdown,
981 .setsockopt = tcp_setsockopt,
982 .getsockopt = tcp_getsockopt,
983 - .sendmsg = tcp_sendmsg,
984 .recvmsg = tcp_recvmsg,
985 .backlog_rcv = tcp_v6_do_rcv,
986 .hash = tcp_v6_hash,
987 diff --git a/net/socket.c b/net/socket.c
988 index afb6085..d9bae01 100644
989 --- a/net/socket.c
990 +++ b/net/socket.c
991 @@ -1147,7 +1147,7 @@ static int __sock_create(int family, int type, int protocol,
992 module_put(pf->owner);
993 err = security_socket_post_create(sock, family, type, protocol, kern);
994 if (err)
995 - goto out_release;
996 + goto out_sock_release;
997 *res = sock;
998
999 return 0;
1000 diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
1001 index bc0bd09..02c2ce6 100644
1002 --- a/sound/core/memalloc.c
1003 +++ b/sound/core/memalloc.c
1004 @@ -27,6 +27,7 @@
1005 #include <linux/pci.h>
1006 #include <linux/slab.h>
1007 #include <linux/mm.h>
1008 +#include <linux/seq_file.h>
1009 #include <asm/uaccess.h>
1010 #include <linux/dma-mapping.h>
1011 #include <linux/moduleparam.h>
1012 @@ -483,10 +484,8 @@ static void free_all_reserved_pages(void)
1013 #define SND_MEM_PROC_FILE "driver/snd-page-alloc"
1014 static struct proc_dir_entry *snd_mem_proc;
1015
1016 -static int snd_mem_proc_read(char *page, char **start, off_t off,
1017 - int count, int *eof, void *data)
1018 +static int snd_mem_proc_read(struct seq_file *seq, void *offset)
1019 {
1020 - int len = 0;
1021 long pages = snd_allocated_pages >> (PAGE_SHIFT-12);
1022 struct list_head *p;
1023 struct snd_mem_list *mem;
1024 @@ -494,44 +493,47 @@ static int snd_mem_proc_read(char *page, char **start, off_t off,
1025 static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" };
1026
1027 mutex_lock(&list_mutex);
1028 - len += snprintf(page + len, count - len,
1029 - "pages : %li bytes (%li pages per %likB)\n",
1030 - pages * PAGE_SIZE, pages, PAGE_SIZE / 1024);
1031 + seq_printf(seq, "pages : %li bytes (%li pages per %likB)\n",
1032 + pages * PAGE_SIZE, pages, PAGE_SIZE / 1024);
1033 devno = 0;
1034 list_for_each(p, &mem_list_head) {
1035 mem = list_entry(p, struct snd_mem_list, list);
1036 devno++;
1037 - len += snprintf(page + len, count - len,
1038 - "buffer %d : ID %08x : type %s\n",
1039 - devno, mem->id, types[mem->buffer.dev.type]);
1040 - len += snprintf(page + len, count - len,
1041 - " addr = 0x%lx, size = %d bytes\n",
1042 - (unsigned long)mem->buffer.addr, (int)mem->buffer.bytes);
1043 + seq_printf(seq, "buffer %d : ID %08x : type %s\n",
1044 + devno, mem->id, types[mem->buffer.dev.type]);
1045 + seq_printf(seq, " addr = 0x%lx, size = %d bytes\n",
1046 + (unsigned long)mem->buffer.addr,
1047 + (int)mem->buffer.bytes);
1048 }
1049 mutex_unlock(&list_mutex);
1050 - return len;
1051 + return 0;
1052 +}
1053 +
1054 +static int snd_mem_proc_open(struct inode *inode, struct file *file)
1055 +{
1056 + return single_open(file, snd_mem_proc_read, NULL);
1057 }
1058
1059 /* FIXME: for pci only - other bus? */
1060 #ifdef CONFIG_PCI
1061 #define gettoken(bufp) strsep(bufp, " \t\n")
1062
1063 -static int snd_mem_proc_write(struct file *file, const char __user *buffer,
1064 - unsigned long count, void *data)
1065 +static ssize_t snd_mem_proc_write(struct file *file, const char __user * buffer,
1066 + size_t count, loff_t * ppos)
1067 {
1068 char buf[128];
1069 char *token, *p;
1070
1071 - if (count > ARRAY_SIZE(buf) - 1)
1072 - count = ARRAY_SIZE(buf) - 1;
1073 + if (count > sizeof(buf) - 1)
1074 + return -EINVAL;
1075 if (copy_from_user(buf, buffer, count))
1076 return -EFAULT;
1077 - buf[ARRAY_SIZE(buf) - 1] = '\0';
1078 + buf[count] = '\0';
1079
1080 p = buf;
1081 token = gettoken(&p);
1082 if (! token || *token == '#')
1083 - return (int)count;
1084 + return count;
1085 if (strcmp(token, "add") == 0) {
1086 char *endp;
1087 int vendor, device, size, buffers;
1088 @@ -552,7 +554,7 @@ static int snd_mem_proc_write(struct file *file, const char __user *buffer,
1089 (buffers = simple_strtol(token, NULL, 0)) <= 0 ||
1090 buffers > 4) {
1091 printk(KERN_ERR "snd-page-alloc: invalid proc write format\n");
1092 - return (int)count;
1093 + return count;
1094 }
1095 vendor &= 0xffff;
1096 device &= 0xffff;
1097 @@ -564,7 +566,7 @@ static int snd_mem_proc_write(struct file *file, const char __user *buffer,
1098 if (pci_set_dma_mask(pci, mask) < 0 ||
1099 pci_set_consistent_dma_mask(pci, mask) < 0) {
1100 printk(KERN_ERR "snd-page-alloc: cannot set DMA mask %lx for pci %04x:%04x\n", mask, vendor, device);
1101 - return (int)count;
1102 + return count;
1103 }
1104 }
1105 for (i = 0; i < buffers; i++) {
1106 @@ -574,7 +576,7 @@ static int snd_mem_proc_write(struct file *file, const char __user *buffer,
1107 size, &dmab) < 0) {
1108 printk(KERN_ERR "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", size);
1109 pci_dev_put(pci);
1110 - return (int)count;
1111 + return count;
1112 }
1113 snd_dma_reserve_buf(&dmab, snd_dma_pci_buf_id(pci));
1114 }
1115 @@ -600,9 +602,21 @@ static int snd_mem_proc_write(struct file *file, const char __user *buffer,
1116 free_all_reserved_pages();
1117 else
1118 printk(KERN_ERR "snd-page-alloc: invalid proc cmd\n");
1119 - return (int)count;
1120 + return count;
1121 }
1122 #endif /* CONFIG_PCI */
1123 +
1124 +static const struct file_operations snd_mem_proc_fops = {
1125 + .owner = THIS_MODULE,
1126 + .open = snd_mem_proc_open,
1127 + .read = seq_read,
1128 +#ifdef CONFIG_PCI
1129 + .write = snd_mem_proc_write,
1130 +#endif
1131 + .llseek = seq_lseek,
1132 + .release = single_release,
1133 +};
1134 +
1135 #endif /* CONFIG_PROC_FS */
1136
1137 /*
1138 @@ -613,12 +627,8 @@ static int __init snd_mem_init(void)
1139 {
1140 #ifdef CONFIG_PROC_FS
1141 snd_mem_proc = create_proc_entry(SND_MEM_PROC_FILE, 0644, NULL);
1142 - if (snd_mem_proc) {
1143 - snd_mem_proc->read_proc = snd_mem_proc_read;
1144 -#ifdef CONFIG_PCI
1145 - snd_mem_proc->write_proc = snd_mem_proc_write;
1146 -#endif
1147 - }
1148 + if (snd_mem_proc)
1149 + snd_mem_proc->proc_fops = &snd_mem_proc_fops;
1150 #endif
1151 return 0;
1152 }