Эх сурвалжийг харах

Merge with http://kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

Jody McIntyre 19 жил өмнө
parent
commit
899a1fc084
100 өөрчлөгдсөн 1699 нэмэгдсэн , 1602 устгасан
  1. 10 2
      CREDITS
  2. 4 2
      Documentation/DocBook/kernel-api.tmpl
  3. 3 1
      Documentation/arm/memory.txt
  4. 5 0
      MAINTAINERS
  5. 1 1
      Makefile
  6. 0 1
      arch/arm/kernel/armksyms.c
  7. 1 2
      arch/arm/kernel/entry-common.S
  8. 12 13
      arch/arm/kernel/signal.c
  9. 5 1
      arch/arm/kernel/vmlinux.lds.S
  10. 0 11
      arch/arm/lib/getuser.S
  11. 1 1
      arch/arm/mach-clps7500/core.c
  12. 1 1
      arch/arm/mach-pxa/tosa.c
  13. 2 1
      arch/arm/mach-sa1100/assabet.c
  14. 1 1
      arch/arm/mm/Makefile
  15. 0 185
      arch/arm/mm/blockops.c
  16. 13 11
      arch/arm/mm/init.c
  17. 1 2
      arch/arm/mm/ioremap.c
  18. 1 3
      arch/i386/kernel/acpi/boot.c
  19. 3 2
      arch/i386/kernel/mpparse.c
  20. 1 0
      arch/ia64/sn/kernel/bte.c
  21. 3 0
      arch/ia64/sn/kernel/sn2/sn2_smp.c
  22. 2 1
      arch/ia64/sn/kernel/sn2/sn_hwperf.c
  23. 6 2
      arch/parisc/kernel/drivers.c
  24. 1 0
      arch/parisc/kernel/entry.S
  25. 1 1
      arch/parisc/kernel/inventory.c
  26. 0 546
      arch/parisc/kernel/ioctl32.c
  27. 92 18
      arch/parisc/kernel/irq.c
  28. 20 13
      arch/parisc/kernel/perf.c
  29. 3 2
      arch/parisc/kernel/ptrace.c
  30. 0 1
      arch/parisc/kernel/signal.c
  31. 18 6
      arch/parisc/kernel/smp.c
  32. 2 1
      arch/parisc/kernel/syscall.S
  33. 1 17
      arch/powerpc/kernel/pci_64.c
  34. 0 3
      arch/powerpc/kernel/ppc_ksyms.c
  35. 0 0
      arch/powerpc/kernel/ptrace-common.h
  36. 2 1
      arch/powerpc/kernel/ptrace.c
  37. 2 1
      arch/powerpc/kernel/ptrace32.c
  38. 2 1
      arch/powerpc/mm/imalloc.c
  39. 2 1
      arch/powerpc/mm/init_64.c
  40. 13 1
      arch/powerpc/mm/mmu_decl.h
  41. 2 1
      arch/powerpc/mm/pgtable_64.c
  42. 4 2
      arch/powerpc/platforms/powermac/smp.c
  43. 8 5
      arch/powerpc/sysdev/mpic.c
  44. 0 6
      block/as-iosched.c
  45. 0 2
      block/cfq-iosched.c
  46. 0 2
      block/deadline-iosched.c
  47. 0 2
      block/elevator.c
  48. 0 2
      block/ll_rw_blk.c
  49. 28 12
      drivers/block/cciss.c
  50. 2 2
      drivers/char/agp/amd64-agp.c
  51. 1 1
      drivers/char/agp/backend.c
  52. 6 0
      drivers/char/agp/via-agp.c
  53. 2 4
      drivers/i2c/busses/i2c-ixp2000.c
  54. 2 5
      drivers/i2c/busses/i2c-ixp4xx.c
  55. 1 1
      drivers/ide/Kconfig
  56. 3 3
      drivers/ide/ide-cd.c
  57. 2 2
      drivers/ide/ide-disk.c
  58. 2 5
      drivers/ide/ide-floppy.c
  59. 0 6
      drivers/ide/ide-io.c
  60. 4 4
      drivers/ide/ide-lib.c
  61. 2 5
      drivers/ide/ide-tape.c
  62. 3 24
      drivers/ide/ide-taskfile.c
  63. 0 47
      drivers/ide/pci/aec62xx.c
  64. 7 2
      drivers/ide/pci/alim15x3.c
  65. 2 3
      drivers/ide/pci/cs5520.c
  66. 7 1
      drivers/ide/pci/siimage.c
  67. 1 0
      drivers/ide/pci/sis5513.c
  68. 135 272
      drivers/ide/pci/via82cxxx.c
  69. 0 14
      drivers/ide/ppc/pmac.c
  70. 1 1
      drivers/ide/setup-pci.c
  71. 1 1
      drivers/infiniband/core/user_mad.c
  72. 18 19
      drivers/infiniband/hw/mthca/mthca_qp.c
  73. 11 6
      drivers/infiniband/ulp/srp/ib_srp.c
  74. 1 0
      drivers/infiniband/ulp/srp/ib_srp.h
  75. 9 3
      drivers/input/gameport/gameport.c
  76. 36 27
      drivers/input/input.c
  77. 68 31
      drivers/input/keyboard/atkbd.c
  78. 10 0
      drivers/input/misc/Kconfig
  79. 1 0
      drivers/input/misc/Makefile
  80. 170 155
      drivers/input/misc/uinput.c
  81. 561 0
      drivers/input/misc/wistron_btns.c
  82. 9 3
      drivers/input/serio/serio.c
  83. 6 6
      drivers/isdn/hisax/Kconfig
  84. 1 1
      drivers/isdn/pcbit/Kconfig
  85. 1 1
      drivers/media/dvb/cinergyT2/cinergyT2.c
  86. 3 2
      drivers/media/video/ir-kbd-gpio.c
  87. 2 0
      drivers/media/video/saa7134/saa7134-input.c
  88. 3 3
      drivers/mtd/maps/ipaq-flash.c
  89. 11 11
      drivers/mtd/maps/ixp2000.c
  90. 1 1
      drivers/mtd/nand/h1910.c
  91. 1 0
      drivers/net/au1000_eth.c
  92. 257 18
      drivers/net/e100.c
  93. 1 1
      drivers/net/fec_8xx/Kconfig
  94. 1 1
      drivers/net/ioc3-eth.c
  95. 2 4
      drivers/net/r8169.c
  96. 25 11
      drivers/net/saa9730.h
  97. 13 4
      drivers/net/smc91x.c
  98. 6 0
      drivers/net/wan/hdlc_cisco.c
  99. 4 0
      drivers/net/wan/hdlc_fr.c
  100. 6 0
      drivers/net/wan/hdlc_generic.c

+ 10 - 2
CREDITS

@@ -611,8 +611,7 @@ S: USA
 N: Randolph Chung
 N: Randolph Chung
 E: tausq@debian.org
 E: tausq@debian.org
 D: Linux/PA-RISC hacker
 D: Linux/PA-RISC hacker
-S: Los Altos, CA 94022
-S: USA
+S: Hong Kong
 
 
 N: Juan Jose Ciarlante
 N: Juan Jose Ciarlante
 W: http://juanjox.kernelnotes.org/
 W: http://juanjox.kernelnotes.org/
@@ -3405,6 +3404,15 @@ S: Chudenicka 8
 S: 10200 Prague 10, Hostivar
 S: 10200 Prague 10, Hostivar
 S: Czech Republic
 S: Czech Republic
 
 
+N: Thibaut Varene
+E: T-Bone@parisc-linux.org
+W: http://www.parisc-linux.org/
+P: 1024D/B7D2F063 E67C 0D43 A75E 12A5 BB1C  FA2F 1E32 C3DA B7D2 F063
+D: PA-RISC port minion, PDC and GSCPS2 drivers, debuglocks and other bits
+D: Some bits in an ARM port, S1D13XXX FB driver, random patches here and there
+D: AD1889 sound driver
+S: Paris, France
+
 N: Heikki Vatiainen
 N: Heikki Vatiainen
 E: hessu@cs.tut.fi
 E: hessu@cs.tut.fi
 D: Co-author of Multi-Protocol Over ATM (MPOA), some LANE hacks
 D: Co-author of Multi-Protocol Over ATM (MPOA), some LANE hacks

+ 4 - 2
Documentation/DocBook/kernel-api.tmpl

@@ -237,8 +237,10 @@ X!Ilib/string.c
      <sect1><title>Driver Support</title>
      <sect1><title>Driver Support</title>
 !Enet/core/dev.c
 !Enet/core/dev.c
 !Enet/ethernet/eth.c
 !Enet/ethernet/eth.c
-!Einclude/linux/etherdevice.h
-!Enet/core/wireless.c
+!Iinclude/linux/etherdevice.h
+<!-- FIXME: Removed for now since no structured comments in source
+X!Enet/core/wireless.c
+-->
      </sect1>
      </sect1>
      <sect1><title>Synchronous PPP</title>
      <sect1><title>Synchronous PPP</title>
 !Edrivers/net/wan/syncppp.c
 !Edrivers/net/wan/syncppp.c

+ 3 - 1
Documentation/arm/memory.txt

@@ -1,7 +1,7 @@
 		Kernel Memory Layout on ARM Linux
 		Kernel Memory Layout on ARM Linux
 
 
 		Russell King <rmk@arm.linux.org.uk>
 		Russell King <rmk@arm.linux.org.uk>
-			May 21, 2004 (2.6.6)
+		     November 17, 2005 (2.6.15)
 
 
 This document describes the virtual memory layout which the Linux
 This document describes the virtual memory layout which the Linux
 kernel uses for ARM processors.  It indicates which regions are
 kernel uses for ARM processors.  It indicates which regions are
@@ -37,6 +37,8 @@ ff000000	ffbfffff	Reserved for future expansion of DMA
 				mapping region.
 				mapping region.
 
 
 VMALLOC_END	feffffff	Free for platform use, recommended.
 VMALLOC_END	feffffff	Free for platform use, recommended.
+				VMALLOC_END must be aligned to a 2MB
+				boundary.
 
 
 VMALLOC_START	VMALLOC_END-1	vmalloc() / ioremap() space.
 VMALLOC_START	VMALLOC_END-1	vmalloc() / ioremap() space.
 				Memory returned by vmalloc/ioremap will
 				Memory returned by vmalloc/ioremap will

+ 5 - 0
MAINTAINERS

@@ -2907,6 +2907,11 @@ M:	zaga@fly.cc.fer.hr
 L:	linux-scsi@vger.kernel.org
 L:	linux-scsi@vger.kernel.org
 S:	Maintained
 S:	Maintained
 
 
+WISTRON LAPTOP BUTTON DRIVER
+P:	Miloslav Trmac
+M:	mitr@volny.cz
+S:	Maintained
+
 WL3501 WIRELESS PCMCIA CARD DRIVER
 WL3501 WIRELESS PCMCIA CARD DRIVER
 P:	Arnaldo Carvalho de Melo
 P:	Arnaldo Carvalho de Melo
 M:	acme@conectiva.com.br
 M:	acme@conectiva.com.br

+ 1 - 1
Makefile

@@ -1,7 +1,7 @@
 VERSION = 2
 VERSION = 2
 PATCHLEVEL = 6
 PATCHLEVEL = 6
 SUBLEVEL = 15
 SUBLEVEL = 15
-EXTRAVERSION =-rc1
+EXTRAVERSION =-rc2
 NAME=Affluent Albatross
 NAME=Affluent Albatross
 
 
 # *DOCUMENTATION*
 # *DOCUMENTATION*

+ 0 - 1
arch/arm/kernel/armksyms.c

@@ -120,7 +120,6 @@ EXPORT_SYMBOL(__arch_strncpy_from_user);
 EXPORT_SYMBOL(__get_user_1);
 EXPORT_SYMBOL(__get_user_1);
 EXPORT_SYMBOL(__get_user_2);
 EXPORT_SYMBOL(__get_user_2);
 EXPORT_SYMBOL(__get_user_4);
 EXPORT_SYMBOL(__get_user_4);
-EXPORT_SYMBOL(__get_user_8);
 
 
 EXPORT_SYMBOL(__put_user_1);
 EXPORT_SYMBOL(__put_user_1);
 EXPORT_SYMBOL(__put_user_2);
 EXPORT_SYMBOL(__put_user_2);

+ 1 - 2
arch/arm/kernel/entry-common.S

@@ -48,8 +48,7 @@ work_pending:
 	mov	r0, sp				@ 'regs'
 	mov	r0, sp				@ 'regs'
 	mov	r2, why				@ 'syscall'
 	mov	r2, why				@ 'syscall'
 	bl	do_notify_resume
 	bl	do_notify_resume
-	disable_irq				@ disable interrupts
-	b	no_work_pending
+	b	ret_slow_syscall		@ Check work again
 
 
 work_resched:
 work_resched:
 	bl	schedule
 	bl	schedule

+ 12 - 13
arch/arm/kernel/signal.c

@@ -595,23 +595,22 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
 	 */
 	 */
 	ret |= !valid_user_regs(regs);
 	ret |= !valid_user_regs(regs);
 
 
-	/*
-	 * Block the signal if we were unsuccessful.
-	 */
 	if (ret != 0) {
 	if (ret != 0) {
-		spin_lock_irq(&tsk->sighand->siglock);
-		sigorsets(&tsk->blocked, &tsk->blocked,
-			  &ka->sa.sa_mask);
-		if (!(ka->sa.sa_flags & SA_NODEFER))
-			sigaddset(&tsk->blocked, sig);
-		recalc_sigpending();
-		spin_unlock_irq(&tsk->sighand->siglock);
+		force_sigsegv(sig, tsk);
+		return;
 	}
 	}
 
 
-	if (ret == 0)
-		return;
+	/*
+	 * Block the signal if we were successful.
+	 */
+	spin_lock_irq(&tsk->sighand->siglock);
+	sigorsets(&tsk->blocked, &tsk->blocked,
+		  &ka->sa.sa_mask);
+	if (!(ka->sa.sa_flags & SA_NODEFER))
+		sigaddset(&tsk->blocked, sig);
+	recalc_sigpending();
+	spin_unlock_irq(&tsk->sighand->siglock);
 
 
-	force_sigsegv(sig, tsk);
 }
 }
 
 
 /*
 /*

+ 5 - 1
arch/arm/kernel/vmlinux.lds.S

@@ -172,6 +172,10 @@ SECTIONS
 	.comment 0 : { *(.comment) }
 	.comment 0 : { *(.comment) }
 }
 }
 
 
-/* those must never be empty */
+/*
+ * These must never be empty
+ * If you have to comment these two assert statements out, your
+ * binutils is too old (for other reasons as well)
+ */
 ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")
 ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")
 ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")
 ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")

+ 0 - 11
arch/arm/lib/getuser.S

@@ -54,15 +54,6 @@ __get_user_4:
 	mov	r0, #0
 	mov	r0, #0
 	mov	pc, lr
 	mov	pc, lr
 
 
-	.global	__get_user_8
-__get_user_8:
-5:	ldrt	r2, [r0], #4
-6:	ldrt	r3, [r0]
-	mov	r0, #0
-	mov	pc, lr
-
-__get_user_bad_8:
-	mov	r3, #0
 __get_user_bad:
 __get_user_bad:
 	mov	r2, #0
 	mov	r2, #0
 	mov	r0, #-EFAULT
 	mov	r0, #-EFAULT
@@ -73,6 +64,4 @@ __get_user_bad:
 	.long	2b, __get_user_bad
 	.long	2b, __get_user_bad
 	.long	3b, __get_user_bad
 	.long	3b, __get_user_bad
 	.long	4b, __get_user_bad
 	.long	4b, __get_user_bad
-	.long	5b, __get_user_bad_8
-	.long	6b, __get_user_bad_8
 .previous
 .previous

+ 1 - 1
arch/arm/mach-clps7500/core.c

@@ -260,7 +260,7 @@ static void __init clps7500_init_irq(void)
 
 
 static struct map_desc cl7500_io_desc[] __initdata = {
 static struct map_desc cl7500_io_desc[] __initdata = {
 	{ 	/* IO space	*/
 	{ 	/* IO space	*/
-		.virtual	= IO_BASE,
+		.virtual	= (unsigned long)IO_BASE,
 		.pfn		= __phys_to_pfn(IO_START),
 		.pfn		= __phys_to_pfn(IO_START),
 		.length		= IO_SIZE,
 		.length		= IO_SIZE,
 		.type		= MT_DEVICE
 		.type		= MT_DEVICE

+ 1 - 1
arch/arm/mach-pxa/tosa.c

@@ -14,7 +14,7 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/major.h>
 #include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/fs.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>

+ 2 - 1
arch/arm/mach-sa1100/assabet.c

@@ -293,7 +293,8 @@ static void __init get_assabet_scr(void)
 	GPDR |= 0x3fc;			/* Configure GPIO 9:2 as outputs */
 	GPDR |= 0x3fc;			/* Configure GPIO 9:2 as outputs */
 	GPSR = 0x3fc;			/* Write 0xFF to GPIO 9:2 */
 	GPSR = 0x3fc;			/* Write 0xFF to GPIO 9:2 */
 	GPDR &= ~(0x3fc);		/* Configure GPIO 9:2 as inputs */
 	GPDR &= ~(0x3fc);		/* Configure GPIO 9:2 as inputs */
-	for(i = 100; i--; scr = GPLR);	/* Read GPIO 9:2 */
+	for(i = 100; i--; )		/* Read GPIO 9:2 */
+		scr = GPLR;
 	GPDR |= 0x3fc;			/*  restore correct pin direction */
 	GPDR |= 0x3fc;			/*  restore correct pin direction */
 	scr &= 0x3fc;			/* save as system configuration byte. */
 	scr &= 0x3fc;			/* save as system configuration byte. */
 	SCR_value = scr;
 	SCR_value = scr;

+ 1 - 1
arch/arm/mm/Makefile

@@ -51,4 +51,4 @@ obj-$(CONFIG_CPU_ARM1026)	+= proc-arm1026.o
 obj-$(CONFIG_CPU_SA110)		+= proc-sa110.o
 obj-$(CONFIG_CPU_SA110)		+= proc-sa110.o
 obj-$(CONFIG_CPU_SA1100)	+= proc-sa1100.o
 obj-$(CONFIG_CPU_SA1100)	+= proc-sa1100.o
 obj-$(CONFIG_CPU_XSCALE)	+= proc-xscale.o
 obj-$(CONFIG_CPU_XSCALE)	+= proc-xscale.o
-obj-$(CONFIG_CPU_V6)		+= proc-v6.o blockops.o
+obj-$(CONFIG_CPU_V6)		+= proc-v6.o

+ 0 - 185
arch/arm/mm/blockops.c

@@ -1,185 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-
-#include <asm/memory.h>
-#include <asm/ptrace.h>
-#include <asm/cacheflush.h>
-#include <asm/traps.h>
-
-extern struct cpu_cache_fns blk_cache_fns;
-
-#define HARVARD_CACHE
-
-/*
- *	blk_flush_kern_dcache_page(kaddr)
- *
- *	Ensure that the data held in the page kaddr is written back
- *	to the page in question.
- *
- *	- kaddr   - kernel address (guaranteed to be page aligned)
- */
-static void __attribute__((naked))
-blk_flush_kern_dcache_page(void *kaddr)
-{
-	asm(
-	"add	r1, r0, %0							\n\
-	sub	r1, r1, %1							\n\
-1:	.word	0xec401f0e	@ mcrr	p15, 0, r0, r1, c14, 0	@ blocking	\n\
-	mov	r0, #0								\n\
-	mcr	p15, 0, r0, c7, c5, 0						\n\
-	mcr	p15, 0, r0, c7, c10, 4						\n\
-	mov	pc, lr"
-	:
-	: "I" (PAGE_SIZE), "I" (L1_CACHE_BYTES));
-}
-
-/*
- *	blk_dma_inv_range(start,end)
- *
- *	Invalidate the data cache within the specified region; we will
- *	be performing a DMA operation in this region and we want to
- *	purge old data in the cache.
- *
- *	- start   - virtual start address of region
- *	- end     - virtual end address of region
- */
-static void __attribute__((naked))
-blk_dma_inv_range_unified(unsigned long start, unsigned long end)
-{
-	asm(
-	"tst	r0, %0								\n\
-	mcrne	p15, 0, r0, c7, c11, 1		@ clean unified line		\n\
-	tst	r1, %0								\n\
-	mcrne	p15, 0, r1, c7, c15, 1		@ clean & invalidate unified line\n\
-	.word	0xec401f06	@ mcrr	p15, 0, r1, r0, c6, 0	@ blocking	\n\
-	mov	r0, #0								\n\
-	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer		\n\
-	mov	pc, lr"
-	:
-	: "I" (L1_CACHE_BYTES - 1));
-}
-
-static void __attribute__((naked))
-blk_dma_inv_range_harvard(unsigned long start, unsigned long end)
-{
-	asm(
-	"tst	r0, %0								\n\
-	mcrne	p15, 0, r0, c7, c10, 1		@ clean D line			\n\
-	tst	r1, %0								\n\
-	mcrne	p15, 0, r1, c7, c14, 1		@ clean & invalidate D line	\n\
-	.word	0xec401f06	@ mcrr	p15, 0, r1, r0, c6, 0	@ blocking	\n\
-	mov	r0, #0								\n\
-	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer		\n\
-	mov	pc, lr"
-	:
-	: "I" (L1_CACHE_BYTES - 1));
-}
-
-/*
- *	blk_dma_clean_range(start,end)
- *	- start   - virtual start address of region
- *	- end     - virtual end address of region
- */
-static void __attribute__((naked))
-blk_dma_clean_range(unsigned long start, unsigned long end)
-{
-	asm(
-	".word	0xec401f0c	@ mcrr	p15, 0, r1, r0, c12, 0	@ blocking	\n\
-	mov	r0, #0								\n\
-	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer		\n\
-	mov	pc, lr");
-}
-
-/*
- *	blk_dma_flush_range(start,end)
- *	- start   - virtual start address of region
- *	- end     - virtual end address of region
- */
-static void __attribute__((naked))
-blk_dma_flush_range(unsigned long start, unsigned long end)
-{
-	asm(
-	".word	0xec401f0e	@ mcrr	p15, 0, r1, r0, c14, 0	@ blocking	\n\
-	mov	pc, lr");
-}
-
-static int blockops_trap(struct pt_regs *regs, unsigned int instr)
-{
-	regs->ARM_r4 |= regs->ARM_r2;
-	regs->ARM_pc += 4;
-	return 0;
-}
-
-static char *func[] = {
-	"Prefetch data range",
-	"Clean+Invalidate data range",
-	"Clean data range",
-	"Invalidate data range",
-	"Invalidate instr range"
-};
-
-static struct undef_hook blockops_hook __initdata = {
-	.instr_mask	= 0x0fffffd0,
-	.instr_val	= 0x0c401f00,
-	.cpsr_mask	= PSR_T_BIT,
-	.cpsr_val	= 0,
-	.fn		= blockops_trap,
-};
-
-static int __init blockops_check(void)
-{
-	register unsigned int err asm("r4") = 0;
-	unsigned int err_pos = 1;
-	unsigned int cache_type;
-	int i;
-
-	asm("mrc p15, 0, %0, c0, c0, 1" : "=r" (cache_type));
-
-	printk("Checking V6 block cache operations:\n");
-	register_undef_hook(&blockops_hook);
-
-	__asm__ ("mov	r0, %0\n\t"
-		"mov	r1, %1\n\t"
-		"mov	r2, #1\n\t"
-		".word	0xec401f2c @ mcrr p15, 0, r1, r0, c12, 2\n\t"
-		"mov	r2, #2\n\t"
-		".word	0xec401f0e @ mcrr p15, 0, r1, r0, c14, 0\n\t"
-		"mov	r2, #4\n\t"
-		".word	0xec401f0c @ mcrr p15, 0, r1, r0, c12, 0\n\t"
-		"mov	r2, #8\n\t"
-		".word	0xec401f06 @ mcrr p15, 0, r1, r0, c6, 0\n\t"
-		"mov	r2, #16\n\t"
-		".word	0xec401f05 @ mcrr p15, 0, r1, r0, c5, 0\n\t"
-		:
-		: "r" (PAGE_OFFSET), "r" (PAGE_OFFSET + 128)
-		: "r0", "r1", "r2");
-
-	unregister_undef_hook(&blockops_hook);
-
-	for (i = 0; i < ARRAY_SIZE(func); i++, err_pos <<= 1)
-		printk("%30s: %ssupported\n", func[i], err & err_pos ? "not " : "");
-
-	if ((err & 8) == 0) {
-		printk(" --> Using %s block cache invalidate\n",
-			cache_type & (1 << 24) ? "harvard" : "unified");
-		if (cache_type & (1 << 24))
-			cpu_cache.dma_inv_range = blk_dma_inv_range_harvard;
-		else
-			cpu_cache.dma_inv_range = blk_dma_inv_range_unified;
-	}
-	if ((err & 4) == 0) {
-		printk(" --> Using block cache clean\n");
-		cpu_cache.dma_clean_range        = blk_dma_clean_range;
-	}
-	if ((err & 2) == 0) {
-		printk(" --> Using block cache clean+invalidate\n");
-		cpu_cache.dma_flush_range        = blk_dma_flush_range;
-		cpu_cache.flush_kern_dcache_page = blk_flush_kern_dcache_page;
-	}
-
-	return 0;
-}
-
-__initcall(blockops_check);

+ 13 - 11
arch/arm/mm/init.c

@@ -420,7 +420,8 @@ static void __init bootmem_init(struct meminfo *mi)
  * Set up device the mappings.  Since we clear out the page tables for all
  * Set up device the mappings.  Since we clear out the page tables for all
  * mappings above VMALLOC_END, we will remove any debug device mappings.
  * mappings above VMALLOC_END, we will remove any debug device mappings.
  * This means you have to be careful how you debug this function, or any
  * This means you have to be careful how you debug this function, or any
- * called function.  (Do it by code inspection!)
+ * called function.  This means you can't use any function or debugging
+ * method which may touch any device, otherwise the kernel _will_ crash.
  */
  */
 static void __init devicemaps_init(struct machine_desc *mdesc)
 static void __init devicemaps_init(struct machine_desc *mdesc)
 {
 {
@@ -428,6 +429,12 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
 	unsigned long addr;
 	unsigned long addr;
 	void *vectors;
 	void *vectors;
 
 
+	/*
+	 * Allocate the vector page early.
+	 */
+	vectors = alloc_bootmem_low_pages(PAGE_SIZE);
+	BUG_ON(!vectors);
+
 	for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
 	for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
 		pmd_clear(pmd_off_k(addr));
 		pmd_clear(pmd_off_k(addr));
 
 
@@ -461,12 +468,6 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
 	create_mapping(&map);
 	create_mapping(&map);
 #endif
 #endif
 
 
-	flush_cache_all();
-	local_flush_tlb_all();
-
-	vectors = alloc_bootmem_low_pages(PAGE_SIZE);
-	BUG_ON(!vectors);
-
 	/*
 	/*
 	 * Create a mapping for the machine vectors at the high-vectors
 	 * Create a mapping for the machine vectors at the high-vectors
 	 * location (0xffff0000).  If we aren't using high-vectors, also
 	 * location (0xffff0000).  If we aren't using high-vectors, also
@@ -491,12 +492,13 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
 		mdesc->map_io();
 		mdesc->map_io();
 
 
 	/*
 	/*
-	 * Finally flush the tlb again - this ensures that we're in a
-	 * consistent state wrt the writebuffer if the writebuffer needs
-	 * draining.  After this point, we can start to touch devices
-	 * again.
+	 * Finally flush the caches and tlb to ensure that we're in a
+	 * consistent state wrt the writebuffer.  This also ensures that
+	 * any write-allocated cache lines in the vector page are written
+	 * back.  After this point, we can start to touch devices again.
 	 */
 	 */
 	local_flush_tlb_all();
 	local_flush_tlb_all();
+	flush_cache_all();
 }
 }
 
 
 /*
 /*

+ 1 - 2
arch/arm/mm/ioremap.c

@@ -130,8 +130,7 @@ remap_area_pages(unsigned long start, unsigned long phys_addr,
  * mapping.  See include/asm-arm/proc-armv/pgtable.h for more information.
  * mapping.  See include/asm-arm/proc-armv/pgtable.h for more information.
  */
  */
 void __iomem *
 void __iomem *
-__ioremap(unsigned long phys_addr, size_t size, unsigned long flags,
-	  unsigned long align)
+__ioremap(unsigned long phys_addr, size_t size, unsigned long flags)
 {
 {
 	void * addr;
 	void * addr;
 	struct vm_struct * area;
 	struct vm_struct * area;

+ 1 - 3
arch/i386/kernel/acpi/boot.c

@@ -248,9 +248,7 @@ acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end)
 
 
 	acpi_table_print_madt_entry(header);
 	acpi_table_print_madt_entry(header);
 
 
-	/* no utility in registering a disabled processor */
-	if (processor->flags.enabled == 0)
-		return 0;
+	/* Register even disabled CPUs for cpu hotplug */
 
 
 	x86_acpiid_to_apicid[processor->acpi_id] = processor->id;
 	x86_acpiid_to_apicid[processor->acpi_id] = processor->id;
 
 

+ 3 - 2
arch/i386/kernel/mpparse.c

@@ -220,8 +220,9 @@ static void __devinit MP_processor_info (struct mpc_config_processor *m)
 	num_processors++;
 	num_processors++;
 
 
 	if ((num_processors > 8) &&
 	if ((num_processors > 8) &&
-	    APIC_XAPIC(ver) &&
-	    (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL))
+	    ((APIC_XAPIC(ver) &&
+	     (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)) ||
+	     (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)))
 		def_to_bigsmp = 1;
 		def_to_bigsmp = 1;
 	else
 	else
 		def_to_bigsmp = 0;
 		def_to_bigsmp = 0;

+ 1 - 0
arch/ia64/sn/kernel/bte.c

@@ -137,6 +137,7 @@ retry_bteop:
 			bte = bte_if_on_node(nasid_to_try[nasid_index],bte_if_index);
 			bte = bte_if_on_node(nasid_to_try[nasid_index],bte_if_index);
 
 
 			if (bte == NULL) {
 			if (bte == NULL) {
+				nasid_index++;
 				continue;
 				continue;
 			}
 			}
 
 

+ 3 - 0
arch/ia64/sn/kernel/sn2/sn2_smp.c

@@ -492,6 +492,9 @@ static struct proc_dir_entry *proc_sn2_ptc;
 
 
 static int __init sn2_ptc_init(void)
 static int __init sn2_ptc_init(void)
 {
 {
+	if (!ia64_platform_is("sn2"))
+		return -ENOSYS;
+
 	if (!(proc_sn2_ptc = create_proc_entry(PTC_BASENAME, 0444, NULL))) {
 	if (!(proc_sn2_ptc = create_proc_entry(PTC_BASENAME, 0444, NULL))) {
 		printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME);
 		printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME);
 		return -EINVAL;
 		return -EINVAL;

+ 2 - 1
arch/ia64/sn/kernel/sn2/sn_hwperf.c

@@ -743,13 +743,14 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, u64 arg)
 		if ((r = sn_hwperf_enum_objects(&nobj, &objs)) == 0) {
 		if ((r = sn_hwperf_enum_objects(&nobj, &objs)) == 0) {
 			memset(p, 0, a.sz);
 			memset(p, 0, a.sz);
 			for (i = 0; i < nobj; i++) {
 			for (i = 0; i < nobj; i++) {
+				int cpuobj_index = 0;
 				if (!SN_HWPERF_IS_NODE(objs + i))
 				if (!SN_HWPERF_IS_NODE(objs + i))
 					continue;
 					continue;
 				node = sn_hwperf_obj_to_cnode(objs + i);
 				node = sn_hwperf_obj_to_cnode(objs + i);
 				for_each_online_cpu(j) {
 				for_each_online_cpu(j) {
 					if (node != cpu_to_node(j))
 					if (node != cpu_to_node(j))
 						continue;
 						continue;
-					cpuobj = (struct sn_hwperf_object_info *) p + j;
+					cpuobj = (struct sn_hwperf_object_info *) p + cpuobj_index++;
 					slice = 'a' + cpuid_to_slice(j);
 					slice = 'a' + cpuid_to_slice(j);
 					cdata = cpu_data(j);
 					cdata = cpu_data(j);
 					cpuobj->id = j;
 					cpuobj->id = j;

+ 6 - 2
arch/parisc/kernel/drivers.c

@@ -499,8 +499,12 @@ alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path)
 
 
 	dev = create_parisc_device(mod_path);
 	dev = create_parisc_device(mod_path);
 	if (dev->id.hw_type != HPHW_FAULTY) {
 	if (dev->id.hw_type != HPHW_FAULTY) {
-		printk("Two devices have hardware path %s.  Please file a bug with HP.\n"
-			"In the meantime, you could try rearranging your cards.\n", parisc_pathname(dev));
+		printk(KERN_ERR "Two devices have hardware path [%s].  "
+				"IODC data for second device: "
+				"%02x%02x%02x%02x%02x%02x\n"
+				"Rearranging GSC cards sometimes helps\n",
+			parisc_pathname(dev), iodc_data[0], iodc_data[1],
+			iodc_data[3], iodc_data[4], iodc_data[5], iodc_data[6]);
 		return NULL;
 		return NULL;
 	}
 	}
 
 

+ 1 - 0
arch/parisc/kernel/entry.S

@@ -1846,6 +1846,7 @@ sys_clone_wrapper:
 	ldo	-16(%r30),%r29		/* Reference param save area */
 	ldo	-16(%r30),%r29		/* Reference param save area */
 #endif
 #endif
 
 
+	/* WARNING - Clobbers r19 and r21, userspace must save these! */
 	STREG	%r2,PT_GR19(%r1)	/* save for child */
 	STREG	%r2,PT_GR19(%r1)	/* save for child */
 	STREG	%r30,PT_GR21(%r1)
 	STREG	%r30,PT_GR21(%r1)
 	BL	sys_clone,%r2
 	BL	sys_clone,%r2

+ 1 - 1
arch/parisc/kernel/inventory.c

@@ -188,7 +188,7 @@ pat_query_module(ulong pcell_loc, ulong mod_index)
 	temp = pa_pdc_cell.cba;
 	temp = pa_pdc_cell.cba;
 	dev = alloc_pa_dev(PAT_GET_CBA(temp), &pa_pdc_cell.mod_path);
 	dev = alloc_pa_dev(PAT_GET_CBA(temp), &pa_pdc_cell.mod_path);
 	if (!dev) {
 	if (!dev) {
-		return PDC_NE_MOD;
+		return PDC_OK;
 	}
 	}
 
 
 	/* alloc_pa_dev sets dev->hpa */
 	/* alloc_pa_dev sets dev->hpa */

+ 0 - 546
arch/parisc/kernel/ioctl32.c

@@ -19,536 +19,6 @@
 #define CODE
 #define CODE
 #include "compat_ioctl.c"
 #include "compat_ioctl.c"
 
 
-/* Use this to get at 32-bit user passed pointers. 
-   See sys_sparc32.c for description about these. */
-#define A(__x) ((unsigned long)(__x))
-/* The same for use with copy_from_user() and copy_to_user(). */
-#define B(__x) ((void *)(unsigned long)(__x))
-
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-/* This really belongs in include/linux/drm.h -DaveM */
-#include "../../../drivers/char/drm/drm.h"
-
-typedef struct drm32_version {
-	int    version_major;	  /* Major version			    */
-	int    version_minor;	  /* Minor version			    */
-	int    version_patchlevel;/* Patch level			    */
-	int    name_len;	  /* Length of name buffer		    */
-	u32    name;		  /* Name of driver			    */
-	int    date_len;	  /* Length of date buffer		    */
-	u32    date;		  /* User-space buffer to hold date	    */
-	int    desc_len;	  /* Length of desc buffer		    */
-	u32    desc;		  /* User-space buffer to hold desc	    */
-} drm32_version_t;
-#define DRM32_IOCTL_VERSION    DRM_IOWR(0x00, drm32_version_t)
-
-static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-	drm32_version_t *uversion = (drm32_version_t *)arg;
-	char *name_ptr, *date_ptr, *desc_ptr;
-	u32 tmp1, tmp2, tmp3;
-	drm_version_t kversion;
-	mm_segment_t old_fs;
-	int ret;
-
-	memset(&kversion, 0, sizeof(kversion));
-	if (get_user(kversion.name_len, &uversion->name_len) ||
-	    get_user(kversion.date_len, &uversion->date_len) ||
-	    get_user(kversion.desc_len, &uversion->desc_len) ||
-	    get_user(tmp1, &uversion->name) ||
-	    get_user(tmp2, &uversion->date) ||
-	    get_user(tmp3, &uversion->desc))
-		return -EFAULT;
-
-	name_ptr = (char *) A(tmp1);
-	date_ptr = (char *) A(tmp2);
-	desc_ptr = (char *) A(tmp3);
-
-	ret = -ENOMEM;
-	if (kversion.name_len && name_ptr) {
-		kversion.name = kmalloc(kversion.name_len, GFP_KERNEL);
-		if (!kversion.name)
-			goto out;
-	}
-	if (kversion.date_len && date_ptr) {
-		kversion.date = kmalloc(kversion.date_len, GFP_KERNEL);
-		if (!kversion.date)
-			goto out;
-	}
-	if (kversion.desc_len && desc_ptr) {
-		kversion.desc = kmalloc(kversion.desc_len, GFP_KERNEL);
-		if (!kversion.desc)
-			goto out;
-	}
-
-        old_fs = get_fs();
-	set_fs(KERNEL_DS);
-        ret = sys_ioctl (fd, DRM_IOCTL_VERSION, (unsigned long)&kversion);
-        set_fs(old_fs);
-
-	if (!ret) {
-		if ((kversion.name &&
-		     copy_to_user(name_ptr, kversion.name, kversion.name_len)) ||
-		    (kversion.date &&
-		     copy_to_user(date_ptr, kversion.date, kversion.date_len)) ||
-		    (kversion.desc &&
-		     copy_to_user(desc_ptr, kversion.desc, kversion.desc_len)))
-			ret = -EFAULT;
-		if (put_user(kversion.version_major, &uversion->version_major) ||
-		    put_user(kversion.version_minor, &uversion->version_minor) ||
-		    put_user(kversion.version_patchlevel, &uversion->version_patchlevel) ||
-		    put_user(kversion.name_len, &uversion->name_len) ||
-		    put_user(kversion.date_len, &uversion->date_len) ||
-		    put_user(kversion.desc_len, &uversion->desc_len))
-			ret = -EFAULT;
-	}
-
-out:
-	kfree(kversion.name);
-	kfree(kversion.date);
-	kfree(kversion.desc);
-	return ret;
-}
-
-typedef struct drm32_unique {
-	int	unique_len;	  /* Length of unique			    */
-	u32	unique;		  /* Unique name for driver instantiation   */
-} drm32_unique_t;
-#define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
-#define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
-
-static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-	drm32_unique_t *uarg = (drm32_unique_t *)arg;
-	drm_unique_t karg;
-	mm_segment_t old_fs;
-	char *uptr;
-	u32 tmp;
-	int ret;
-
-	if (get_user(karg.unique_len, &uarg->unique_len))
-		return -EFAULT;
-	karg.unique = NULL;
-
-	if (get_user(tmp, &uarg->unique))
-		return -EFAULT;
-
-	uptr = (char *) A(tmp);
-
-	if (uptr) {
-		karg.unique = kmalloc(karg.unique_len, GFP_KERNEL);
-		if (!karg.unique)
-			return -ENOMEM;
-		if (cmd == DRM32_IOCTL_SET_UNIQUE &&
-		    copy_from_user(karg.unique, uptr, karg.unique_len)) {
-			kfree(karg.unique);
-			return -EFAULT;
-		}
-	}
-
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-	if (cmd == DRM32_IOCTL_GET_UNIQUE)
-		ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)&karg);
-	else
-		ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)&karg);
-        set_fs(old_fs);
-
-	if (!ret) {
-		if (cmd == DRM32_IOCTL_GET_UNIQUE &&
-		    uptr != NULL &&
-		    copy_to_user(uptr, karg.unique, karg.unique_len))
-			ret = -EFAULT;
-		if (put_user(karg.unique_len, &uarg->unique_len))
-			ret = -EFAULT;
-	}
-
-	kfree(karg.unique);
-	return ret;
-}
-
-typedef struct drm32_map {
-	u32		offset;	 /* Requested physical address (0 for SAREA)*/
-	u32		size;	 /* Requested physical size (bytes)	    */
-	drm_map_type_t	type;	 /* Type of memory to map		    */
-	drm_map_flags_t flags;	 /* Flags				    */
-	u32		handle;  /* User-space: "Handle" to pass to mmap    */
-				 /* Kernel-space: kernel-virtual address    */
-	int		mtrr;	 /* MTRR slot used			    */
-				 /* Private data			    */
-} drm32_map_t;
-#define DRM32_IOCTL_ADD_MAP    DRM_IOWR(0x15, drm32_map_t)
-
-static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-	drm32_map_t *uarg = (drm32_map_t *) arg;
-	drm_map_t karg;
-	mm_segment_t old_fs;
-	u32 tmp;
-	int ret;
-
-	ret  = get_user(karg.offset, &uarg->offset);
-	ret |= get_user(karg.size, &uarg->size);
-	ret |= get_user(karg.type, &uarg->type);
-	ret |= get_user(karg.flags, &uarg->flags);
-	ret |= get_user(tmp, &uarg->handle);
-	ret |= get_user(karg.mtrr, &uarg->mtrr);
-	if (ret)
-		return -EFAULT;
-
-	karg.handle = (void *) A(tmp);
-
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-	ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg);
-	set_fs(old_fs);
-
-	if (!ret) {
-		ret  = put_user(karg.offset, &uarg->offset);
-		ret |= put_user(karg.size, &uarg->size);
-		ret |= put_user(karg.type, &uarg->type);
-		ret |= put_user(karg.flags, &uarg->flags);
-		tmp = (u32) (long)karg.handle;
-		ret |= put_user(tmp, &uarg->handle);
-		ret |= put_user(karg.mtrr, &uarg->mtrr);
-		if (ret)
-			ret = -EFAULT;
-	}
-
-	return ret;
-}
-
-typedef struct drm32_buf_info {
-	int	       count;	/* Entries in list			     */
-	u32	       list;    /* (drm_buf_desc_t *) */ 
-} drm32_buf_info_t;
-#define DRM32_IOCTL_INFO_BUFS  DRM_IOWR(0x18, drm32_buf_info_t)
-
-static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-	drm32_buf_info_t *uarg = (drm32_buf_info_t *)arg;
-	drm_buf_desc_t *ulist;
-	drm_buf_info_t karg;
-	mm_segment_t old_fs;
-	int orig_count, ret;
-	u32 tmp;
-
-	if (get_user(karg.count, &uarg->count) ||
-	    get_user(tmp, &uarg->list))
-		return -EFAULT;
-
-	ulist = (drm_buf_desc_t *) A(tmp);
-
-	orig_count = karg.count;
-
-	karg.list = kmalloc(karg.count * sizeof(drm_buf_desc_t), GFP_KERNEL);
-	if (!karg.list)
-		return -EFAULT;
-
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-	ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long) &karg);
-	set_fs(old_fs);
-
-	if (!ret) {
-		if (karg.count <= orig_count &&
-		    (copy_to_user(ulist, karg.list,
-				  karg.count * sizeof(drm_buf_desc_t))))
-			ret = -EFAULT;
-		if (put_user(karg.count, &uarg->count))
-			ret = -EFAULT;
-	}
-
-	kfree(karg.list);
-	return ret;
-}
-
-typedef struct drm32_buf_free {
-	int	       count;
-	u32	       list;	/* (int *) */
-} drm32_buf_free_t;
-#define DRM32_IOCTL_FREE_BUFS  DRM_IOW( 0x1a, drm32_buf_free_t)
-
-static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-	drm32_buf_free_t *uarg = (drm32_buf_free_t *)arg;
-	drm_buf_free_t karg;
-	mm_segment_t old_fs;
-	int *ulist;
-	int ret;
-	u32 tmp;
-
-	if (get_user(karg.count, &uarg->count) ||
-	    get_user(tmp, &uarg->list))
-		return -EFAULT;
-
-	ulist = (int *) A(tmp);
-
-	karg.list = kmalloc(karg.count * sizeof(int), GFP_KERNEL);
-	if (!karg.list)
-		return -ENOMEM;
-
-	ret = -EFAULT;
-	if (copy_from_user(karg.list, ulist, (karg.count * sizeof(int))))
-		goto out;
-
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-	ret = sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long) &karg);
-	set_fs(old_fs);
-
-out:
-	kfree(karg.list);
-	return ret;
-}
-
-typedef struct drm32_buf_pub {
-	int		  idx;	       /* Index into master buflist	     */
-	int		  total;       /* Buffer size			     */
-	int		  used;	       /* Amount of buffer in use (for DMA)  */
-	u32		  address;     /* Address of buffer (void *)	     */
-} drm32_buf_pub_t;
-
-typedef struct drm32_buf_map {
-	int	      count;	/* Length of buflist			    */
-	u32	      virtual;	/* Mmaped area in user-virtual (void *)	    */
-	u32 	      list;	/* Buffer information (drm_buf_pub_t *)	    */
-} drm32_buf_map_t;
-#define DRM32_IOCTL_MAP_BUFS   DRM_IOWR(0x19, drm32_buf_map_t)
-
-static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-	drm32_buf_map_t *uarg = (drm32_buf_map_t *)arg;
-	drm32_buf_pub_t *ulist;
-	drm_buf_map_t karg;
-	mm_segment_t old_fs;
-	int orig_count, ret, i;
-	u32 tmp1, tmp2;
-
-	if (get_user(karg.count, &uarg->count) ||
-	    get_user(tmp1, &uarg->virtual) ||
-	    get_user(tmp2, &uarg->list))
-		return -EFAULT;
-
-	karg.virtual = (void *) A(tmp1);
-	ulist = (drm32_buf_pub_t *) A(tmp2);
-
-	orig_count = karg.count;
-
-	karg.list = kmalloc(karg.count * sizeof(drm_buf_pub_t), GFP_KERNEL);
-	if (!karg.list)
-		return -ENOMEM;
-
-	ret = -EFAULT;
-	for (i = 0; i < karg.count; i++) {
-		if (get_user(karg.list[i].idx, &ulist[i].idx) ||
-		    get_user(karg.list[i].total, &ulist[i].total) ||
-		    get_user(karg.list[i].used, &ulist[i].used) ||
-		    get_user(tmp1, &ulist[i].address))
-			goto out;
-
-		karg.list[i].address = (void *) A(tmp1);
-	}
-
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-	ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) &karg);
-	set_fs(old_fs);
-
-	if (!ret) {
-		for (i = 0; i < orig_count; i++) {
-			tmp1 = (u32) (long) karg.list[i].address;
-			if (put_user(karg.list[i].idx, &ulist[i].idx) ||
-			    put_user(karg.list[i].total, &ulist[i].total) ||
-			    put_user(karg.list[i].used, &ulist[i].used) ||
-			    put_user(tmp1, &ulist[i].address)) {
-				ret = -EFAULT;
-				goto out;
-			}
-		}
-		if (put_user(karg.count, &uarg->count))
-			ret = -EFAULT;
-	}
-
-out:
-	kfree(karg.list);
-	return ret;
-}
-
-typedef struct drm32_dma {
-				/* Indices here refer to the offset into
-				   buflist in drm_buf_get_t.  */
-	int		context;	  /* Context handle		    */
-	int		send_count;	  /* Number of buffers to send	    */
-	u32		send_indices;	  /* List of handles to buffers (int *) */
-	u32		send_sizes;	  /* Lengths of data to send (int *) */
-	drm_dma_flags_t flags;		  /* Flags			    */
-	int		request_count;	  /* Number of buffers requested    */
-	int		request_size;	  /* Desired size for buffers	    */
-	u32		request_indices;  /* Buffer information (int *)	    */
-	u32		request_sizes;    /* (int *) */
-	int		granted_count;	  /* Number of buffers granted	    */
-} drm32_dma_t;
-#define DRM32_IOCTL_DMA	     DRM_IOWR(0x29, drm32_dma_t)
-
-/* RED PEN	The DRM layer blindly dereferences the send/request
- * 		indice/size arrays even though they are userland
- * 		pointers.  -DaveM
- */
-static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-	drm32_dma_t *uarg = (drm32_dma_t *) arg;
-	int *u_si, *u_ss, *u_ri, *u_rs;
-	drm_dma_t karg;
-	mm_segment_t old_fs;
-	int ret;
-	u32 tmp1, tmp2, tmp3, tmp4;
-
-	karg.send_indices = karg.send_sizes = NULL;
-	karg.request_indices = karg.request_sizes = NULL;
-
-	if (get_user(karg.context, &uarg->context) ||
-	    get_user(karg.send_count, &uarg->send_count) ||
-	    get_user(tmp1, &uarg->send_indices) ||
-	    get_user(tmp2, &uarg->send_sizes) ||
-	    get_user(karg.flags, &uarg->flags) ||
-	    get_user(karg.request_count, &uarg->request_count) ||
-	    get_user(karg.request_size, &uarg->request_size) ||
-	    get_user(tmp3, &uarg->request_indices) ||
-	    get_user(tmp4, &uarg->request_sizes) ||
-	    get_user(karg.granted_count, &uarg->granted_count))
-		return -EFAULT;
-
-	u_si = (int *) A(tmp1);
-	u_ss = (int *) A(tmp2);
-	u_ri = (int *) A(tmp3);
-	u_rs = (int *) A(tmp4);
-
-	if (karg.send_count) {
-		karg.send_indices = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
-		karg.send_sizes = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
-
-		ret = -ENOMEM;
-		if (!karg.send_indices || !karg.send_sizes)
-			goto out;
-
-		ret = -EFAULT;
-		if (copy_from_user(karg.send_indices, u_si,
-				   (karg.send_count * sizeof(int))) ||
-		    copy_from_user(karg.send_sizes, u_ss,
-				   (karg.send_count * sizeof(int))))
-			goto out;
-	}
-
-	if (karg.request_count) {
-		karg.request_indices = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
-		karg.request_sizes = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
-
-		ret = -ENOMEM;
-		if (!karg.request_indices || !karg.request_sizes)
-			goto out;
-
-		ret = -EFAULT;
-		if (copy_from_user(karg.request_indices, u_ri,
-				   (karg.request_count * sizeof(int))) ||
-		    copy_from_user(karg.request_sizes, u_rs,
-				   (karg.request_count * sizeof(int))))
-			goto out;
-	}
-
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-	ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long) &karg);
-	set_fs(old_fs);
-
-	if (!ret) {
-		if (put_user(karg.context, &uarg->context) ||
-		    put_user(karg.send_count, &uarg->send_count) ||
-		    put_user(karg.flags, &uarg->flags) ||
-		    put_user(karg.request_count, &uarg->request_count) ||
-		    put_user(karg.request_size, &uarg->request_size) ||
-		    put_user(karg.granted_count, &uarg->granted_count))
-			ret = -EFAULT;
-
-		if (karg.send_count) {
-			if (copy_to_user(u_si, karg.send_indices,
-					 (karg.send_count * sizeof(int))) ||
-			    copy_to_user(u_ss, karg.send_sizes,
-					 (karg.send_count * sizeof(int))))
-				ret = -EFAULT;
-		}
-		if (karg.request_count) {
-			if (copy_to_user(u_ri, karg.request_indices,
-					 (karg.request_count * sizeof(int))) ||
-			    copy_to_user(u_rs, karg.request_sizes,
-					 (karg.request_count * sizeof(int))))
-				ret = -EFAULT;
-		}
-	}
-
-out:
-	kfree(karg.send_indices);
-	kfree(karg.send_sizes);
-	kfree(karg.request_indices);
-	kfree(karg.request_sizes);
-	return ret;
-}
-
-typedef struct drm32_ctx_res {
-	int		count;
-	u32		contexts; /* (drm_ctx_t *) */
-} drm32_ctx_res_t;
-#define DRM32_IOCTL_RES_CTX    DRM_IOWR(0x26, drm32_ctx_res_t)
-
-static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-	drm32_ctx_res_t *uarg = (drm32_ctx_res_t *) arg;
-	drm_ctx_t *ulist;
-	drm_ctx_res_t karg;
-	mm_segment_t old_fs;
-	int orig_count, ret;
-	u32 tmp;
-
-	karg.contexts = NULL;
-	if (get_user(karg.count, &uarg->count) ||
-	    get_user(tmp, &uarg->contexts))
-		return -EFAULT;
-
-	ulist = (drm_ctx_t *) A(tmp);
-
-	orig_count = karg.count;
-	if (karg.count && ulist) {
-		karg.contexts = kmalloc((karg.count * sizeof(drm_ctx_t)), GFP_KERNEL);
-		if (!karg.contexts)
-			return -ENOMEM;
-		if (copy_from_user(karg.contexts, ulist,
-				   (karg.count * sizeof(drm_ctx_t)))) {
-			kfree(karg.contexts);
-			return -EFAULT;
-		}
-	}
-
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-	ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long) &karg);
-	set_fs(old_fs);
-
-	if (!ret) {
-		if (orig_count) {
-			if (copy_to_user(ulist, karg.contexts,
-					 (orig_count * sizeof(drm_ctx_t))))
-				ret = -EFAULT;
-		}
-		if (put_user(karg.count, &uarg->count))
-			ret = -EFAULT;
-	}
-
-	kfree(karg.contexts);
-	return ret;
-}
-
-#endif
-
 #define HANDLE_IOCTL(cmd, handler) { cmd, (ioctl_trans_handler_t)handler, NULL },
 #define HANDLE_IOCTL(cmd, handler) { cmd, (ioctl_trans_handler_t)handler, NULL },
 #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd, sys_ioctl) 
 #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd, sys_ioctl) 
 
 
@@ -561,11 +31,6 @@ IOCTL_TABLE_START
 #define DECLARES
 #define DECLARES
 #include "compat_ioctl.c"
 #include "compat_ioctl.c"
 
 
-/* PA-specific ioctls */
-COMPATIBLE_IOCTL(PA_PERF_ON)
-COMPATIBLE_IOCTL(PA_PERF_OFF)
-COMPATIBLE_IOCTL(PA_PERF_VERSION)
-
 /* And these ioctls need translation */
 /* And these ioctls need translation */
 HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc)
 HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc)
 HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc)
 HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc)
@@ -590,17 +55,6 @@ HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
 COMPATIBLE_IOCTL(RTC_EPOCH_SET)
 COMPATIBLE_IOCTL(RTC_EPOCH_SET)
 #endif
 #endif
 
 
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version);
-HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique);
-HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique);
-HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap);
-HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma);
-HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx);
-#endif /* DRM */
 IOCTL_TABLE_END
 IOCTL_TABLE_END
 
 
 int ioctl_table_size = ARRAY_SIZE(ioctl_start);
 int ioctl_table_size = ARRAY_SIZE(ioctl_start);

+ 92 - 18
arch/parisc/kernel/irq.c

@@ -30,6 +30,9 @@
 #include <linux/seq_file.h>
 #include <linux/seq_file.h>
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/types.h>
+#include <asm/io.h>
+
+#include <asm/smp.h>
 
 
 #undef PARISC_IRQ_CR16_COUNTS
 #undef PARISC_IRQ_CR16_COUNTS
 
 
@@ -43,26 +46,34 @@ extern irqreturn_t ipi_interrupt(int, void *, struct pt_regs *);
 */
 */
 static volatile unsigned long cpu_eiem = 0;
 static volatile unsigned long cpu_eiem = 0;
 
 
-static void cpu_set_eiem(void *info)
-{
-	set_eiem((unsigned long) info);
-}
-
-static inline void cpu_disable_irq(unsigned int irq)
+static void cpu_disable_irq(unsigned int irq)
 {
 {
 	unsigned long eirr_bit = EIEM_MASK(irq);
 	unsigned long eirr_bit = EIEM_MASK(irq);
 
 
 	cpu_eiem &= ~eirr_bit;
 	cpu_eiem &= ~eirr_bit;
-        on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
+	/* Do nothing on the other CPUs.  If they get this interrupt,
+	 * The & cpu_eiem in the do_cpu_irq_mask() ensures they won't
+	 * handle it, and the set_eiem() at the bottom will ensure it
+	 * then gets disabled */
 }
 }
 
 
 static void cpu_enable_irq(unsigned int irq)
 static void cpu_enable_irq(unsigned int irq)
 {
 {
 	unsigned long eirr_bit = EIEM_MASK(irq);
 	unsigned long eirr_bit = EIEM_MASK(irq);
 
 
-	mtctl(eirr_bit, 23);	/* clear EIRR bit before unmasking */
 	cpu_eiem |= eirr_bit;
 	cpu_eiem |= eirr_bit;
-        on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
+
+	/* FIXME: while our interrupts aren't nested, we cannot reset
+	 * the eiem mask if we're already in an interrupt.  Once we
+	 * implement nested interrupts, this can go away
+	 */
+	if (!in_interrupt())
+		set_eiem(cpu_eiem);
+
+	/* This is just a simple NOP IPI.  But what it does is cause
+	 * all the other CPUs to do a set_eiem(cpu_eiem) at the end
+	 * of the interrupt handler */
+	smp_send_all_nop();
 }
 }
 
 
 static unsigned int cpu_startup_irq(unsigned int irq)
 static unsigned int cpu_startup_irq(unsigned int irq)
@@ -74,6 +85,35 @@ static unsigned int cpu_startup_irq(unsigned int irq)
 void no_ack_irq(unsigned int irq) { }
 void no_ack_irq(unsigned int irq) { }
 void no_end_irq(unsigned int irq) { }
 void no_end_irq(unsigned int irq) { }
 
 
+#ifdef CONFIG_SMP
+int cpu_check_affinity(unsigned int irq, cpumask_t *dest)
+{
+	int cpu_dest;
+
+	/* timer and ipi have to always be received on all CPUs */
+	if (irq == TIMER_IRQ || irq == IPI_IRQ) {
+		/* Bad linux design decision.  The mask has already
+		 * been set; we must reset it */
+		irq_affinity[irq] = CPU_MASK_ALL;
+		return -EINVAL;
+	}
+
+	/* whatever mask they set, we just allow one CPU */
+	cpu_dest = first_cpu(*dest);
+	*dest = cpumask_of_cpu(cpu_dest);
+
+	return 0;
+}
+
+static void cpu_set_affinity_irq(unsigned int irq, cpumask_t dest)
+{
+	if (cpu_check_affinity(irq, &dest))
+		return;
+
+	irq_affinity[irq] = dest;
+}
+#endif
+
 static struct hw_interrupt_type cpu_interrupt_type = {
 static struct hw_interrupt_type cpu_interrupt_type = {
 	.typename	= "CPU",
 	.typename	= "CPU",
 	.startup	= cpu_startup_irq,
 	.startup	= cpu_startup_irq,
@@ -82,7 +122,9 @@ static struct hw_interrupt_type cpu_interrupt_type = {
 	.disable	= cpu_disable_irq,
 	.disable	= cpu_disable_irq,
 	.ack		= no_ack_irq,
 	.ack		= no_ack_irq,
 	.end		= no_end_irq,
 	.end		= no_end_irq,
-//	.set_affinity	= cpu_set_affinity_irq,
+#ifdef CONFIG_SMP
+	.set_affinity	= cpu_set_affinity_irq,
+#endif
 };
 };
 
 
 int show_interrupts(struct seq_file *p, void *v)
 int show_interrupts(struct seq_file *p, void *v)
@@ -219,6 +261,17 @@ int txn_alloc_irq(unsigned int bits_wide)
 	return -1;
 	return -1;
 }
 }
 
 
+
+unsigned long txn_affinity_addr(unsigned int irq, int cpu)
+{
+#ifdef CONFIG_SMP
+	irq_affinity[irq] = cpumask_of_cpu(cpu);
+#endif
+
+	return cpu_data[cpu].txn_addr;
+}
+
+
 unsigned long txn_alloc_addr(unsigned int virt_irq)
 unsigned long txn_alloc_addr(unsigned int virt_irq)
 {
 {
 	static int next_cpu = -1;
 	static int next_cpu = -1;
@@ -233,7 +286,7 @@ unsigned long txn_alloc_addr(unsigned int virt_irq)
 	if (next_cpu >= NR_CPUS) 
 	if (next_cpu >= NR_CPUS) 
 		next_cpu = 0;	/* nothing else, assign monarch */
 		next_cpu = 0;	/* nothing else, assign monarch */
 
 
-	return cpu_data[next_cpu].txn_addr;
+	return txn_affinity_addr(virt_irq, next_cpu);
 }
 }
 
 
 
 
@@ -250,10 +303,11 @@ void do_cpu_irq_mask(struct pt_regs *regs)
 	irq_enter();
 	irq_enter();
 
 
 	/*
 	/*
-	 * Only allow interrupt processing to be interrupted by the
-	 * timer tick
+	 * Don't allow TIMER or IPI nested interrupts.
+	 * Allowing any single interrupt to nest can lead to that CPU
+	 * handling interrupts with all enabled interrupts unmasked.
 	 */
 	 */
-	set_eiem(EIEM_MASK(TIMER_IRQ));
+	set_eiem(0UL);
 
 
 	/* 1) only process IRQs that are enabled/unmasked (cpu_eiem)
 	/* 1) only process IRQs that are enabled/unmasked (cpu_eiem)
 	 * 2) We loop here on EIRR contents in order to avoid
 	 * 2) We loop here on EIRR contents in order to avoid
@@ -267,23 +321,41 @@ void do_cpu_irq_mask(struct pt_regs *regs)
 		if (!eirr_val)
 		if (!eirr_val)
 			break;
 			break;
 
 
-		if (eirr_val & EIEM_MASK(TIMER_IRQ))
-			set_eiem(0);
-
 		mtctl(eirr_val, 23); /* reset bits we are going to process */
 		mtctl(eirr_val, 23); /* reset bits we are going to process */
 
 
 		/* Work our way from MSb to LSb...same order we alloc EIRs */
 		/* Work our way from MSb to LSb...same order we alloc EIRs */
 		for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) {
 		for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) {
+#ifdef CONFIG_SMP
+			cpumask_t dest = irq_affinity[irq];
+#endif
 			if (!(bit & eirr_val))
 			if (!(bit & eirr_val))
 				continue;
 				continue;
 
 
 			/* clear bit in mask - can exit loop sooner */
 			/* clear bit in mask - can exit loop sooner */
 			eirr_val &= ~bit;
 			eirr_val &= ~bit;
 
 
+#ifdef CONFIG_SMP
+			/* FIXME: because generic set affinity mucks
+			 * with the affinity before sending it to us
+			 * we can get the situation where the affinity is
+			 * wrong for our CPU type interrupts */
+			if (irq != TIMER_IRQ && irq != IPI_IRQ &&
+			    !cpu_isset(smp_processor_id(), dest)) {
+				int cpu = first_cpu(dest);
+
+				printk(KERN_DEBUG "redirecting irq %d from CPU %d to %d\n",
+				       irq, smp_processor_id(), cpu);
+				gsc_writel(irq + CPU_IRQ_BASE,
+					   cpu_data[cpu].hpa);
+				continue;
+			}
+#endif
+
 			__do_IRQ(irq, regs);
 			__do_IRQ(irq, regs);
 		}
 		}
 	}
 	}
-	set_eiem(cpu_eiem);
+
+	set_eiem(cpu_eiem);	/* restore original mask */
 	irq_exit();
 	irq_exit();
 }
 }
 
 
@@ -291,12 +363,14 @@ void do_cpu_irq_mask(struct pt_regs *regs)
 static struct irqaction timer_action = {
 static struct irqaction timer_action = {
 	.handler = timer_interrupt,
 	.handler = timer_interrupt,
 	.name = "timer",
 	.name = "timer",
+	.flags = SA_INTERRUPT,
 };
 };
 
 
 #ifdef CONFIG_SMP
 #ifdef CONFIG_SMP
 static struct irqaction ipi_action = {
 static struct irqaction ipi_action = {
 	.handler = ipi_interrupt,
 	.handler = ipi_interrupt,
 	.name = "IPI",
 	.name = "IPI",
+	.flags = SA_INTERRUPT,
 };
 };
 #endif
 #endif
 
 

+ 20 - 13
arch/parisc/kernel/perf.c

@@ -196,8 +196,7 @@ static int perf_open(struct inode *inode, struct file *file);
 static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos);
 static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos);
 static ssize_t perf_write(struct file *file, const char __user *buf, size_t count, 
 static ssize_t perf_write(struct file *file, const char __user *buf, size_t count, 
 	loff_t *ppos);
 	loff_t *ppos);
-static int perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-	unsigned long arg);
+static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 static void perf_start_counters(void);
 static void perf_start_counters(void);
 static int perf_stop_counters(uint32_t *raddr);
 static int perf_stop_counters(uint32_t *raddr);
 static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num);
 static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num);
@@ -438,48 +437,56 @@ static void perf_patch_images(void)
  * must be running on the processor that you wish to change.
  * must be running on the processor that you wish to change.
  */
  */
 
 
-static int perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-	unsigned long arg)
+static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 {
 	long error_start;
 	long error_start;
-	uint32_t raddr[4];	
+	uint32_t raddr[4];
+	int error = 0;
 
 
+	lock_kernel();
 	switch (cmd) {
 	switch (cmd) {
 
 
 	    case PA_PERF_ON:
 	    case PA_PERF_ON:
 			/* Start the counters */
 			/* Start the counters */
 			perf_start_counters();
 			perf_start_counters();
-			return 0;
+			break;
 
 
 	    case PA_PERF_OFF:
 	    case PA_PERF_OFF:
 			error_start = perf_stop_counters(raddr);
 			error_start = perf_stop_counters(raddr);
 			if (error_start != 0) {
 			if (error_start != 0) {
 				printk(KERN_ERR "perf_off: perf_stop_counters = %ld\n", error_start);
 				printk(KERN_ERR "perf_off: perf_stop_counters = %ld\n", error_start);
-				return -EFAULT;	
+				error = -EFAULT;
+				break;
 			}
 			}
 
 
 			/* copy out the Counters */
 			/* copy out the Counters */
 			if (copy_to_user((void __user *)arg, raddr, 
 			if (copy_to_user((void __user *)arg, raddr, 
 					sizeof (raddr)) != 0) {
 					sizeof (raddr)) != 0) {
-				return -EFAULT;
+				error =  -EFAULT;
+				break;
 			}
 			}
-			return 0;
+			break;
 
 
 	    case PA_PERF_VERSION:
 	    case PA_PERF_VERSION:
   	  		/* Return the version # */
   	  		/* Return the version # */
-			return put_user(PERF_VERSION, (int *)arg);
+			error = put_user(PERF_VERSION, (int *)arg);
+			break;
 
 
 	    default:
 	    default:
-  	 		break;
+  	 		error = -ENOTTY;
 	}
 	}
-	return -ENOTTY;
+
+	unlock_kernel();
+
+	return error;
 }
 }
 
 
 static struct file_operations perf_fops = {
 static struct file_operations perf_fops = {
 	.llseek = no_llseek,
 	.llseek = no_llseek,
 	.read = perf_read,
 	.read = perf_read,
 	.write = perf_write,
 	.write = perf_write,
-	.ioctl = perf_ioctl,
+	.unlocked_ioctl = perf_ioctl,
+	.compat_ioctl = perf_ioctl,
 	.open = perf_open,
 	.open = perf_open,
 	.release = perf_release
 	.release = perf_release
 };
 };

+ 3 - 2
arch/parisc/kernel/ptrace.c

@@ -264,6 +264,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 		 * sigkill.  perhaps it should be put in the status
 		 * sigkill.  perhaps it should be put in the status
 		 * that it wants to exit.
 		 * that it wants to exit.
 		 */
 		 */
+		ret = 0;
 		DBG("sys_ptrace(KILL)\n");
 		DBG("sys_ptrace(KILL)\n");
 		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
 		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
 			goto out_tsk;
 			goto out_tsk;
@@ -344,11 +345,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 
 
 	case PTRACE_GETEVENTMSG:
 	case PTRACE_GETEVENTMSG:
                 ret = put_user(child->ptrace_message, (unsigned int __user *) data);
                 ret = put_user(child->ptrace_message, (unsigned int __user *) data);
-		goto out;
+		goto out_tsk;
 
 
 	default:
 	default:
 		ret = ptrace_request(child, request, addr, data);
 		ret = ptrace_request(child, request, addr, data);
-		goto out;
+		goto out_tsk;
 	}
 	}
 
 
 out_wake_notrap:
 out_wake_notrap:

+ 0 - 1
arch/parisc/kernel/signal.c

@@ -296,7 +296,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 	struct rt_sigframe __user *frame;
 	struct rt_sigframe __user *frame;
 	unsigned long rp, usp;
 	unsigned long rp, usp;
 	unsigned long haddr, sigframe_size;
 	unsigned long haddr, sigframe_size;
-	struct siginfo si;
 	int err = 0;
 	int err = 0;
 #ifdef __LP64__
 #ifdef __LP64__
 	compat_int_t compat_val;
 	compat_int_t compat_val;

+ 18 - 6
arch/parisc/kernel/smp.c

@@ -181,12 +181,19 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 		while (ops) {
 		while (ops) {
 			unsigned long which = ffz(~ops);
 			unsigned long which = ffz(~ops);
 
 
+			ops &= ~(1 << which);
+
 			switch (which) {
 			switch (which) {
+			case IPI_NOP:
+#if (kDEBUG>=100)
+				printk(KERN_DEBUG "CPU%d IPI_NOP\n",this_cpu);
+#endif /* kDEBUG */
+				break;
+				
 			case IPI_RESCHEDULE:
 			case IPI_RESCHEDULE:
 #if (kDEBUG>=100)
 #if (kDEBUG>=100)
 				printk(KERN_DEBUG "CPU%d IPI_RESCHEDULE\n",this_cpu);
 				printk(KERN_DEBUG "CPU%d IPI_RESCHEDULE\n",this_cpu);
 #endif /* kDEBUG */
 #endif /* kDEBUG */
-				ops &= ~(1 << IPI_RESCHEDULE);
 				/*
 				/*
 				 * Reschedule callback.  Everything to be
 				 * Reschedule callback.  Everything to be
 				 * done is done by the interrupt return path.
 				 * done is done by the interrupt return path.
@@ -197,7 +204,6 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 #if (kDEBUG>=100)
 #if (kDEBUG>=100)
 				printk(KERN_DEBUG "CPU%d IPI_CALL_FUNC\n",this_cpu);
 				printk(KERN_DEBUG "CPU%d IPI_CALL_FUNC\n",this_cpu);
 #endif /* kDEBUG */
 #endif /* kDEBUG */
-				ops &= ~(1 << IPI_CALL_FUNC);
 				{
 				{
 					volatile struct smp_call_struct *data;
 					volatile struct smp_call_struct *data;
 					void (*func)(void *info);
 					void (*func)(void *info);
@@ -231,7 +237,6 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 #if (kDEBUG>=100)
 #if (kDEBUG>=100)
 				printk(KERN_DEBUG "CPU%d IPI_CPU_START\n",this_cpu);
 				printk(KERN_DEBUG "CPU%d IPI_CPU_START\n",this_cpu);
 #endif /* kDEBUG */
 #endif /* kDEBUG */
-				ops &= ~(1 << IPI_CPU_START);
 #ifdef ENTRY_SYS_CPUS
 #ifdef ENTRY_SYS_CPUS
 				p->state = STATE_RUNNING;
 				p->state = STATE_RUNNING;
 #endif
 #endif
@@ -241,7 +246,6 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 #if (kDEBUG>=100)
 #if (kDEBUG>=100)
 				printk(KERN_DEBUG "CPU%d IPI_CPU_STOP\n",this_cpu);
 				printk(KERN_DEBUG "CPU%d IPI_CPU_STOP\n",this_cpu);
 #endif /* kDEBUG */
 #endif /* kDEBUG */
-				ops &= ~(1 << IPI_CPU_STOP);
 #ifdef ENTRY_SYS_CPUS
 #ifdef ENTRY_SYS_CPUS
 #else
 #else
 				halt_processor();
 				halt_processor();
@@ -252,13 +256,11 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 #if (kDEBUG>=100)
 #if (kDEBUG>=100)
 				printk(KERN_DEBUG "CPU%d is alive!\n",this_cpu);
 				printk(KERN_DEBUG "CPU%d is alive!\n",this_cpu);
 #endif /* kDEBUG */
 #endif /* kDEBUG */
-				ops &= ~(1 << IPI_CPU_TEST);
 				break;
 				break;
 
 
 			default:
 			default:
 				printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n",
 				printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n",
 					this_cpu, which);
 					this_cpu, which);
-				ops &= ~(1 << which);
 				return IRQ_NONE;
 				return IRQ_NONE;
 			} /* Switch */
 			} /* Switch */
 		} /* while (ops) */
 		} /* while (ops) */
@@ -312,6 +314,12 @@ smp_send_start(void)	{ send_IPI_allbutself(IPI_CPU_START); }
 void 
 void 
 smp_send_reschedule(int cpu) { send_IPI_single(cpu, IPI_RESCHEDULE); }
 smp_send_reschedule(int cpu) { send_IPI_single(cpu, IPI_RESCHEDULE); }
 
 
+void
+smp_send_all_nop(void)
+{
+	send_IPI_allbutself(IPI_NOP);
+}
+
 
 
 /**
 /**
  * Run a function on all other CPUs.
  * Run a function on all other CPUs.
@@ -338,6 +346,10 @@ smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
 
 
 	/* Can deadlock when called with interrupts disabled */
 	/* Can deadlock when called with interrupts disabled */
 	WARN_ON(irqs_disabled());
 	WARN_ON(irqs_disabled());
+
+	/* can also deadlock if IPIs are disabled */
+	WARN_ON((get_eiem() & (1UL<<(CPU_IRQ_MAX - IPI_IRQ))) == 0);
+
 	
 	
 	data.func = func;
 	data.func = func;
 	data.info = info;
 	data.info = info;

+ 2 - 1
arch/parisc/kernel/syscall.S

@@ -164,7 +164,7 @@ linux_gateway_entry:
 #endif
 #endif
 	STREG	%r2,  TASK_PT_GR30(%r1)		/* ... and save it */
 	STREG	%r2,  TASK_PT_GR30(%r1)		/* ... and save it */
 	
 	
-	STREG	%r20, TASK_PT_GR20(%r1)
+	STREG	%r20, TASK_PT_GR20(%r1)		/* Syscall number */
 	STREG	%r21, TASK_PT_GR21(%r1)
 	STREG	%r21, TASK_PT_GR21(%r1)
 	STREG	%r22, TASK_PT_GR22(%r1)
 	STREG	%r22, TASK_PT_GR22(%r1)
 	STREG	%r23, TASK_PT_GR23(%r1)		/* 4th argument */
 	STREG	%r23, TASK_PT_GR23(%r1)		/* 4th argument */
@@ -527,6 +527,7 @@ lws_compare_and_swap:
 		We *must* giveup this call and fail.
 		We *must* giveup this call and fail.
 	*/
 	*/
 	ldw	4(%sr2,%r20), %r28			/* Load thread register */
 	ldw	4(%sr2,%r20), %r28			/* Load thread register */
+	/* WARNING: If cr27 cycles to the same value we have problems */
 	mfctl	%cr27, %r21				/* Get current thread register */
 	mfctl	%cr27, %r21				/* Get current thread register */
 	cmpb,<>,n	%r21, %r28, cas_lock		/* Called recursive? */
 	cmpb,<>,n	%r21, %r28, cas_lock		/* Called recursive? */
 	b	lws_exit				/* Return error! */
 	b	lws_exit				/* Return error! */

+ 1 - 17
arch/powerpc/kernel/pci_64.c

@@ -40,7 +40,7 @@
 #endif
 #endif
 
 
 unsigned long pci_probe_only = 1;
 unsigned long pci_probe_only = 1;
-unsigned long pci_assign_all_buses = 0;
+int pci_assign_all_buses = 0;
 
 
 /*
 /*
  * legal IO pages under MAX_ISA_PORT.  This is to ensure we don't touch
  * legal IO pages under MAX_ISA_PORT.  This is to ensure we don't touch
@@ -55,11 +55,6 @@ static void fixup_resource(struct resource *res, struct pci_dev *dev);
 static void do_bus_setup(struct pci_bus *bus);
 static void do_bus_setup(struct pci_bus *bus);
 #endif
 #endif
 
 
-unsigned int pcibios_assign_all_busses(void)
-{
-	return pci_assign_all_buses;
-}
-
 /* pci_io_base -- the base address from which io bars are offsets.
 /* pci_io_base -- the base address from which io bars are offsets.
  * This is the lowest I/O base address (so bar values are always positive),
  * This is the lowest I/O base address (so bar values are always positive),
  * and it *must* be the start of ISA space if an ISA bus exists because
  * and it *must* be the start of ISA space if an ISA bus exists because
@@ -1186,17 +1181,6 @@ void phbs_remap_io(void)
 		remap_bus_range(hose->bus);
 		remap_bus_range(hose->bus);
 }
 }
 
 
-/*
- * ppc64 can have multifunction devices that do not respond to function 0.
- * In this case we must scan all functions.
- * XXX this can go now, we use the OF device tree in all the
- * cases that caused problems. -- paulus
- */
-int pcibios_scan_all_fns(struct pci_bus *bus, int devfn)
-{
-       return 0;
-}
-
 static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
 static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
 {
 {
 	struct pci_controller *hose = pci_bus_to_host(dev->bus);
 	struct pci_controller *hose = pci_bus_to_host(dev->bus);

+ 0 - 3
arch/powerpc/kernel/ppc_ksyms.c

@@ -146,9 +146,6 @@ EXPORT_SYMBOL(pci_bus_io_base);
 EXPORT_SYMBOL(pci_bus_io_base_phys);
 EXPORT_SYMBOL(pci_bus_io_base_phys);
 EXPORT_SYMBOL(pci_bus_mem_base_phys);
 EXPORT_SYMBOL(pci_bus_mem_base_phys);
 EXPORT_SYMBOL(pci_bus_to_hose);
 EXPORT_SYMBOL(pci_bus_to_hose);
-EXPORT_SYMBOL(pci_resource_to_bus);
-EXPORT_SYMBOL(pci_phys_to_bus);
-EXPORT_SYMBOL(pci_bus_to_phys);
 #endif /* CONFIG_PCI */
 #endif /* CONFIG_PCI */
 
 
 #ifdef CONFIG_NOT_COHERENT_CACHE
 #ifdef CONFIG_NOT_COHERENT_CACHE

+ 0 - 0
include/asm-ppc64/ptrace-common.h → arch/powerpc/kernel/ptrace-common.h


+ 2 - 1
arch/powerpc/kernel/ptrace.c

@@ -36,8 +36,9 @@
 #include <asm/page.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/system.h>
+
 #ifdef CONFIG_PPC64
 #ifdef CONFIG_PPC64
-#include <asm/ptrace-common.h>
+#include "ptrace-common.h"
 #endif
 #endif
 
 
 #ifdef CONFIG_PPC32
 #ifdef CONFIG_PPC32

+ 2 - 1
arch/powerpc/kernel/ptrace32.c

@@ -33,7 +33,8 @@
 #include <asm/page.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/system.h>
-#include <asm/ptrace-common.h>
+
+#include "ptrace-common.h"
 
 
 /*
 /*
  * does not yet catch signals sent when the child dies.
  * does not yet catch signals sent when the child dies.

+ 2 - 1
arch/powerpc/mm/imalloc.c

@@ -14,9 +14,10 @@
 #include <asm/pgalloc.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 #include <asm/semaphore.h>
 #include <asm/semaphore.h>
-#include <asm/imalloc.h>
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
 
 
+#include "mmu_decl.h"
+
 static DECLARE_MUTEX(imlist_sem);
 static DECLARE_MUTEX(imlist_sem);
 struct vm_struct * imlist = NULL;
 struct vm_struct * imlist = NULL;
 
 

+ 2 - 1
arch/powerpc/mm/init_64.c

@@ -64,7 +64,8 @@
 #include <asm/iommu.h>
 #include <asm/iommu.h>
 #include <asm/abs_addr.h>
 #include <asm/abs_addr.h>
 #include <asm/vdso.h>
 #include <asm/vdso.h>
-#include <asm/imalloc.h>
+
+#include "mmu_decl.h"
 
 
 #ifdef DEBUG
 #ifdef DEBUG
 #define DBG(fmt...) printk(fmt)
 #define DBG(fmt...) printk(fmt)

+ 13 - 1
arch/powerpc/mm/mmu_decl.h

@@ -33,7 +33,6 @@ extern void invalidate_tlbcam_entry(int index);
 
 
 extern int __map_without_bats;
 extern int __map_without_bats;
 extern unsigned long ioremap_base;
 extern unsigned long ioremap_base;
-extern unsigned long ioremap_bot;
 extern unsigned int rtas_data, rtas_size;
 extern unsigned int rtas_data, rtas_size;
 
 
 extern PTE *Hash, *Hash_end;
 extern PTE *Hash, *Hash_end;
@@ -42,6 +41,7 @@ extern unsigned long Hash_size, Hash_mask;
 extern unsigned int num_tlbcam_entries;
 extern unsigned int num_tlbcam_entries;
 #endif
 #endif
 
 
+extern unsigned long ioremap_bot;
 extern unsigned long __max_low_memory;
 extern unsigned long __max_low_memory;
 extern unsigned long __initial_memory_limit;
 extern unsigned long __initial_memory_limit;
 extern unsigned long total_memory;
 extern unsigned long total_memory;
@@ -84,4 +84,16 @@ static inline void flush_HPTE(unsigned context, unsigned long va,
 	else
 	else
 		_tlbie(va);
 		_tlbie(va);
 }
 }
+#else /* CONFIG_PPC64 */
+/* imalloc region types */
+#define IM_REGION_UNUSED	0x1
+#define IM_REGION_SUBSET	0x2
+#define IM_REGION_EXISTS	0x4
+#define IM_REGION_OVERLAP	0x8
+#define IM_REGION_SUPERSET	0x10
+
+extern struct vm_struct * im_get_free_area(unsigned long size);
+extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
+				      int region_type);
+extern void im_free(void *addr);
 #endif
 #endif

+ 2 - 1
arch/powerpc/mm/pgtable_64.c

@@ -64,7 +64,8 @@
 #include <asm/iommu.h>
 #include <asm/iommu.h>
 #include <asm/abs_addr.h>
 #include <asm/abs_addr.h>
 #include <asm/vdso.h>
 #include <asm/vdso.h>
-#include <asm/imalloc.h>
+
+#include "mmu_decl.h"
 
 
 unsigned long ioremap_bot = IMALLOC_BASE;
 unsigned long ioremap_bot = IMALLOC_BASE;
 static unsigned long phbs_io_bot = PHBS_IO_BASE;
 static unsigned long phbs_io_bot = PHBS_IO_BASE;

+ 4 - 2
arch/powerpc/platforms/powermac/smp.c

@@ -34,6 +34,7 @@
 #include <linux/errno.h>
 #include <linux/errno.h>
 #include <linux/hardirq.h>
 #include <linux/hardirq.h>
 #include <linux/cpu.h>
 #include <linux/cpu.h>
+#include <linux/compiler.h>
 
 
 #include <asm/ptrace.h>
 #include <asm/ptrace.h>
 #include <asm/atomic.h>
 #include <asm/atomic.h>
@@ -631,8 +632,9 @@ void smp_core99_give_timebase(void)
 	mb();
 	mb();
 
 
 	/* wait for the secondary to have taken it */
 	/* wait for the secondary to have taken it */
-	for (t = 100000; t > 0 && sec_tb_reset; --t)
-		udelay(10);
+	/* note: can't use udelay here, since it needs the timebase running */
+	for (t = 10000000; t > 0 && sec_tb_reset; --t)
+		barrier();
 	if (sec_tb_reset)
 	if (sec_tb_reset)
 		/* XXX BUG_ON here? */
 		/* XXX BUG_ON here? */
 		printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");
 		printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");

+ 8 - 5
arch/powerpc/sysdev/mpic.c

@@ -361,7 +361,8 @@ static void mpic_enable_irq(unsigned int irq)
 	DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
 	DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
 
 
 	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
 	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
-		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & ~MPIC_VECPRI_MASK);
+		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
+		       ~MPIC_VECPRI_MASK);
 
 
 	/* make sure mask gets to controller before we return to user */
 	/* make sure mask gets to controller before we return to user */
 	do {
 	do {
@@ -381,7 +382,8 @@ static void mpic_disable_irq(unsigned int irq)
 	DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
 	DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
 
 
 	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
 	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
-		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | MPIC_VECPRI_MASK);
+		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
+		       MPIC_VECPRI_MASK);
 
 
 	/* make sure mask gets to controller before we return to user */
 	/* make sure mask gets to controller before we return to user */
 	do {
 	do {
@@ -735,12 +737,13 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
 
 
 	spin_lock_irqsave(&mpic_lock, flags);
 	spin_lock_irqsave(&mpic_lock, flags);
 	if (is_ipi) {
 	if (is_ipi) {
-		reg = mpic_ipi_read(irq - mpic->ipi_offset) & MPIC_VECPRI_PRIORITY_MASK;
+		reg = mpic_ipi_read(irq - mpic->ipi_offset) &
+			~MPIC_VECPRI_PRIORITY_MASK;
 		mpic_ipi_write(irq - mpic->ipi_offset,
 		mpic_ipi_write(irq - mpic->ipi_offset,
 			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
 			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
 	} else {
 	} else {
-		reg = mpic_irq_read(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI)
-			& MPIC_VECPRI_PRIORITY_MASK;
+		reg = mpic_irq_read(irq - mpic->irq_offset,MPIC_IRQ_VECTOR_PRI)
+			& ~MPIC_VECPRI_PRIORITY_MASK;
 		mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI,
 		mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI,
 			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
 			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
 	}
 	}

+ 0 - 6
block/as-iosched.c

@@ -1,6 +1,4 @@
 /*
 /*
- *  linux/drivers/block/as-iosched.c
- *
  *  Anticipatory & deadline i/o scheduler.
  *  Anticipatory & deadline i/o scheduler.
  *
  *
  *  Copyright (C) 2002 Jens Axboe <axboe@suse.de>
  *  Copyright (C) 2002 Jens Axboe <axboe@suse.de>
@@ -1373,10 +1371,6 @@ static void as_add_request(request_queue_t *q, struct request *rq)
 	struct as_rq *alias;
 	struct as_rq *alias;
 	int data_dir;
 	int data_dir;
 
 
-	if (arq->state != AS_RQ_PRESCHED) {
-		printk("arq->state: %d\n", arq->state);
-		WARN_ON(1);
-	}
 	arq->state = AS_RQ_NEW;
 	arq->state = AS_RQ_NEW;
 
 
 	if (rq_data_dir(arq->request) == READ
 	if (rq_data_dir(arq->request) == READ

+ 0 - 2
block/cfq-iosched.c

@@ -1,6 +1,4 @@
 /*
 /*
- *  linux/drivers/block/cfq-iosched.c
- *
  *  CFQ, or complete fairness queueing, disk scheduler.
  *  CFQ, or complete fairness queueing, disk scheduler.
  *
  *
  *  Based on ideas from a previously unfinished io
  *  Based on ideas from a previously unfinished io

+ 0 - 2
block/deadline-iosched.c

@@ -1,6 +1,4 @@
 /*
 /*
- *  linux/drivers/block/deadline-iosched.c
- *
  *  Deadline i/o scheduler.
  *  Deadline i/o scheduler.
  *
  *
  *  Copyright (C) 2002 Jens Axboe <axboe@suse.de>
  *  Copyright (C) 2002 Jens Axboe <axboe@suse.de>

+ 0 - 2
block/elevator.c

@@ -1,6 +1,4 @@
 /*
 /*
- *  linux/drivers/block/elevator.c
- *
  *  Block device elevator/IO-scheduler.
  *  Block device elevator/IO-scheduler.
  *
  *
  *  Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
  *  Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE

+ 0 - 2
block/ll_rw_blk.c

@@ -1,6 +1,4 @@
 /*
 /*
- *  linux/drivers/block/ll_rw_blk.c
- *
  * Copyright (C) 1991, 1992 Linus Torvalds
  * Copyright (C) 1991, 1992 Linus Torvalds
  * Copyright (C) 1994,      Karl Keyte: Added support for disk statistics
  * Copyright (C) 1994,      Karl Keyte: Added support for disk statistics
  * Elevator latency, (C) 2000  Andrea Arcangeli <andrea@suse.de> SuSE
  * Elevator latency, (C) 2000  Andrea Arcangeli <andrea@suse.de> SuSE

+ 28 - 12
drivers/block/cciss.c

@@ -1017,10 +1017,11 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
 				status = -ENOMEM;
 				status = -ENOMEM;
 				goto cleanup1;
 				goto cleanup1;
 			}
 			}
-			if (ioc->Request.Type.Direction == XFER_WRITE &&
-				copy_from_user(buff[sg_used], data_ptr, sz)) {
+			if (ioc->Request.Type.Direction == XFER_WRITE) {
+				if (copy_from_user(buff[sg_used], data_ptr, sz)) {
 					status = -ENOMEM;
 					status = -ENOMEM;
-					goto cleanup1;			
+					goto cleanup1;
+				}
 			} else {
 			} else {
 				memset(buff[sg_used], 0, sz);
 				memset(buff[sg_used], 0, sz);
 			}
 			}
@@ -1138,8 +1139,15 @@ static int revalidate_allvol(ctlr_info_t *host)
 
 
 	for(i=0; i< NWD; i++) {
 	for(i=0; i< NWD; i++) {
 		struct gendisk *disk = host->gendisk[i];
 		struct gendisk *disk = host->gendisk[i];
-		if (disk->flags & GENHD_FL_UP)
-			del_gendisk(disk);
+		if (disk) {
+			request_queue_t *q = disk->queue;
+
+			if (disk->flags & GENHD_FL_UP)
+				del_gendisk(disk);
+			if (q)
+				blk_cleanup_queue(q);
+			put_disk(disk);
+		}
 	}
 	}
 
 
         /*
         /*
@@ -1453,10 +1461,13 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
 	 * allows us to delete disk zero but keep the controller registered.
 	 * allows us to delete disk zero but keep the controller registered.
 	*/
 	*/
 	if (h->gendisk[0] != disk){
 	if (h->gendisk[0] != disk){
-		if (disk->flags & GENHD_FL_UP){
-			blk_cleanup_queue(disk->queue);
-		del_gendisk(disk);
-			drv->queue = NULL;
+		if (disk) {
+			request_queue_t *q = disk->queue;
+			if (disk->flags & GENHD_FL_UP)
+				del_gendisk(disk);
+			if (q)	
+				blk_cleanup_queue(q);
+			put_disk(disk);	
 		}
 		}
 	}
 	}
 
 
@@ -3225,9 +3236,14 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
 	/* remove it from the disk list */
 	/* remove it from the disk list */
 	for (j = 0; j < NWD; j++) {
 	for (j = 0; j < NWD; j++) {
 		struct gendisk *disk = hba[i]->gendisk[j];
 		struct gendisk *disk = hba[i]->gendisk[j];
-		if (disk->flags & GENHD_FL_UP) {
-			del_gendisk(disk);
-			blk_cleanup_queue(disk->queue);
+		if (disk) {
+			request_queue_t *q = disk->queue;
+
+			if (disk->flags & GENHD_FL_UP) 
+				del_gendisk(disk);
+			if (q)
+				blk_cleanup_queue(q);
+			put_disk(disk);
 		}
 		}
 	}
 	}
 
 

+ 2 - 2
drivers/char/agp/amd64-agp.c

@@ -416,7 +416,7 @@ static void __devinit amd8151_init(struct pci_dev *pdev, struct agp_bridge_data
 }
 }
 
 
 
 
-static struct aper_size_info_32 uli_sizes[7] =
+static const struct aper_size_info_32 uli_sizes[7] =
 {
 {
 	{256, 65536, 6, 10},
 	{256, 65536, 6, 10},
 	{128, 32768, 5, 9},
 	{128, 32768, 5, 9},
@@ -470,7 +470,7 @@ static int __devinit uli_agp_init(struct pci_dev *pdev)
 }
 }
 
 
 
 
-static struct aper_size_info_32 nforce3_sizes[5] =
+static const struct aper_size_info_32 nforce3_sizes[5] =
 {
 {
 	{512,  131072, 7, 0x00000000 },
 	{512,  131072, 7, 0x00000000 },
 	{256,  65536,  6, 0x00000008 },
 	{256,  65536,  6, 0x00000008 },

+ 1 - 1
drivers/char/agp/backend.c

@@ -97,7 +97,7 @@ void agp_backend_release(struct agp_bridge_data *bridge)
 EXPORT_SYMBOL(agp_backend_release);
 EXPORT_SYMBOL(agp_backend_release);
 
 
 
 
-static struct { int mem, agp; } maxes_table[] = {
+static const struct { int mem, agp; } maxes_table[] = {
 	{0, 0},
 	{0, 0},
 	{32, 4},
 	{32, 4},
 	{64, 28},
 	{64, 28},

+ 6 - 0
drivers/char/agp/via-agp.c

@@ -371,6 +371,11 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata =
 		.device_id	= PCI_DEVICE_ID_VIA_3296_0,
 		.device_id	= PCI_DEVICE_ID_VIA_3296_0,
 		.chipset_name	= "P4M800",
 		.chipset_name	= "P4M800",
 	},
 	},
+	/* P4M800CE */
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_P4M800CE,
+		.chipset_name	= "P4M800CE",
+	},
 
 
 	{ }, /* dummy final entry, always present */
 	{ }, /* dummy final entry, always present */
 };
 };
@@ -511,6 +516,7 @@ static struct pci_device_id agp_via_pci_table[] = {
 	ID(PCI_DEVICE_ID_VIA_3269_0),
 	ID(PCI_DEVICE_ID_VIA_3269_0),
 	ID(PCI_DEVICE_ID_VIA_83_87XX_1),
 	ID(PCI_DEVICE_ID_VIA_83_87XX_1),
 	ID(PCI_DEVICE_ID_VIA_3296_0),
 	ID(PCI_DEVICE_ID_VIA_3296_0),
+	ID(PCI_DEVICE_ID_VIA_P4M800CE),
 	{ }
 	{ }
 };
 };
 
 

+ 2 - 4
drivers/i2c/busses/i2c-ixp2000.c

@@ -36,8 +36,6 @@
 #include <asm/hardware.h>	/* Pick up IXP2000-specific bits */
 #include <asm/hardware.h>	/* Pick up IXP2000-specific bits */
 #include <asm/arch/gpio.h>
 #include <asm/arch/gpio.h>
 
 
-static struct device_driver ixp2000_i2c_driver;
-
 static inline int ixp2000_scl_pin(void *data)
 static inline int ixp2000_scl_pin(void *data)
 {
 {
 	return ((struct ixp2000_i2c_pins*)data)->scl_pin;
 	return ((struct ixp2000_i2c_pins*)data)->scl_pin;
@@ -120,7 +118,7 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev)
 	drv_data->algo_data.timeout = 100;
 	drv_data->algo_data.timeout = 100;
 
 
 	drv_data->adapter.id = I2C_HW_B_IXP2000,
 	drv_data->adapter.id = I2C_HW_B_IXP2000,
-	strlcpy(drv_data->adapter.name, ixp2000_i2c_driver.name,
+	strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
 		I2C_NAME_SIZE);
 		I2C_NAME_SIZE);
 	drv_data->adapter.algo_data = &drv_data->algo_data,
 	drv_data->adapter.algo_data = &drv_data->algo_data,
 
 
@@ -132,7 +130,7 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev)
 	gpio_line_set(gpio->sda_pin, 0);
 	gpio_line_set(gpio->sda_pin, 0);
 
 
 	if ((err = i2c_bit_add_bus(&drv_data->adapter)) != 0) {
 	if ((err = i2c_bit_add_bus(&drv_data->adapter)) != 0) {
-		dev_err(dev, "Could not install, error %d\n", err);
+		dev_err(&plat_dev->dev, "Could not install, error %d\n", err);
 		kfree(drv_data);
 		kfree(drv_data);
 		return err;
 		return err;
 	} 
 	} 

+ 2 - 5
drivers/i2c/busses/i2c-ixp4xx.c

@@ -35,8 +35,6 @@
 
 
 #include <asm/hardware.h>	/* Pick up IXP4xx-specific bits */
 #include <asm/hardware.h>	/* Pick up IXP4xx-specific bits */
 
 
-static struct platform_driver ixp4xx_i2c_driver;
-
 static inline int ixp4xx_scl_pin(void *data)
 static inline int ixp4xx_scl_pin(void *data)
 {
 {
 	return ((struct ixp4xx_i2c_pins*)data)->scl_pin;
 	return ((struct ixp4xx_i2c_pins*)data)->scl_pin;
@@ -128,7 +126,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev)
 	drv_data->algo_data.timeout = 100;
 	drv_data->algo_data.timeout = 100;
 
 
 	drv_data->adapter.id = I2C_HW_B_IXP4XX;
 	drv_data->adapter.id = I2C_HW_B_IXP4XX;
-	strlcpy(drv_data->adapter.name, ixp4xx_i2c_driver.driver.name,
+	strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
 		I2C_NAME_SIZE);
 		I2C_NAME_SIZE);
 	drv_data->adapter.algo_data = &drv_data->algo_data;
 	drv_data->adapter.algo_data = &drv_data->algo_data;
 
 
@@ -140,8 +138,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev)
 	gpio_line_set(gpio->sda_pin, 0);
 	gpio_line_set(gpio->sda_pin, 0);
 
 
 	if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0)) {
 	if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0)) {
-		printk(KERN_ERR "ERROR: Could not install %s\n", 
-				plat_dev->dev.bus_id);
+		printk(KERN_ERR "ERROR: Could not install %s\n", plat_dev->dev.bus_id);
 
 
 		kfree(drv_data);
 		kfree(drv_data);
 		return err;
 		return err;

+ 1 - 1
drivers/ide/Kconfig

@@ -625,7 +625,7 @@ config BLK_DEV_NS87415
 	tristate "NS87415 chipset support"
 	tristate "NS87415 chipset support"
 	help
 	help
 	  This driver adds detection and support for the NS87415 chip
 	  This driver adds detection and support for the NS87415 chip
-	  (used in SPARC64, among others).
+	  (used mainly on SPARC64 and PA-RISC machines).
 
 
 	  Please read the comments at the top of <file:drivers/ide/pci/ns87415.c>.
 	  Please read the comments at the top of <file:drivers/ide/pci/ns87415.c>.
 
 

+ 3 - 3
drivers/ide/ide-cd.c

@@ -3328,8 +3328,8 @@ static ide_proc_entry_t idecd_proc[] = {
 #endif
 #endif
 
 
 static ide_driver_t ide_cdrom_driver = {
 static ide_driver_t ide_cdrom_driver = {
-	.owner			= THIS_MODULE,
 	.gen_driver = {
 	.gen_driver = {
+		.owner		= THIS_MODULE,
 		.name		= "ide-cdrom",
 		.name		= "ide-cdrom",
 		.bus		= &ide_bus_type,
 		.bus		= &ide_bus_type,
 		.probe		= ide_cd_probe,
 		.probe		= ide_cd_probe,
@@ -3510,8 +3510,8 @@ static void __exit ide_cdrom_exit(void)
 {
 {
 	driver_unregister(&ide_cdrom_driver.gen_driver);
 	driver_unregister(&ide_cdrom_driver.gen_driver);
 }
 }
- 
-static int ide_cdrom_init(void)
+
+static int __init ide_cdrom_init(void)
 {
 {
 	return driver_register(&ide_cdrom_driver.gen_driver);
 	return driver_register(&ide_cdrom_driver.gen_driver);
 }
 }

+ 2 - 2
drivers/ide/ide-disk.c

@@ -1089,8 +1089,8 @@ static void ide_device_shutdown(struct device *dev)
 }
 }
 
 
 static ide_driver_t idedisk_driver = {
 static ide_driver_t idedisk_driver = {
-	.owner			= THIS_MODULE,
 	.gen_driver = {
 	.gen_driver = {
+		.owner		= THIS_MODULE,
 		.name		= "ide-disk",
 		.name		= "ide-disk",
 		.bus		= &ide_bus_type,
 		.bus		= &ide_bus_type,
 		.probe		= ide_disk_probe,
 		.probe		= ide_disk_probe,
@@ -1266,7 +1266,7 @@ static void __exit idedisk_exit (void)
 	driver_unregister(&idedisk_driver.gen_driver);
 	driver_unregister(&idedisk_driver.gen_driver);
 }
 }
 
 
-static int idedisk_init (void)
+static int __init idedisk_init(void)
 {
 {
 	return driver_register(&idedisk_driver.gen_driver);
 	return driver_register(&idedisk_driver.gen_driver);
 }
 }

+ 2 - 5
drivers/ide/ide-floppy.c

@@ -1925,8 +1925,8 @@ static ide_proc_entry_t idefloppy_proc[] = {
 static int ide_floppy_probe(struct device *);
 static int ide_floppy_probe(struct device *);
 
 
 static ide_driver_t idefloppy_driver = {
 static ide_driver_t idefloppy_driver = {
-	.owner			= THIS_MODULE,
 	.gen_driver = {
 	.gen_driver = {
+		.owner		= THIS_MODULE,
 		.name		= "ide-floppy",
 		.name		= "ide-floppy",
 		.bus		= &ide_bus_type,
 		.bus		= &ide_bus_type,
 		.probe		= ide_floppy_probe,
 		.probe		= ide_floppy_probe,
@@ -2191,10 +2191,7 @@ static void __exit idefloppy_exit (void)
 	driver_unregister(&idefloppy_driver.gen_driver);
 	driver_unregister(&idefloppy_driver.gen_driver);
 }
 }
 
 
-/*
- *	idefloppy_init will register the driver for each floppy.
- */
-static int idefloppy_init (void)
+static int __init idefloppy_init(void)
 {
 {
 	printk("ide-floppy driver " IDEFLOPPY_VERSION "\n");
 	printk("ide-floppy driver " IDEFLOPPY_VERSION "\n");
 	return driver_register(&idefloppy_driver.gen_driver);
 	return driver_register(&idefloppy_driver.gen_driver);

+ 0 - 6
drivers/ide/ide-io.c

@@ -1629,12 +1629,6 @@ EXPORT_SYMBOL(ide_init_drive_cmd);
  *	for the new rq to be completed.  This is VERY DANGEROUS, and is
  *	for the new rq to be completed.  This is VERY DANGEROUS, and is
  *	intended for careful use by the ATAPI tape/cdrom driver code.
  *	intended for careful use by the ATAPI tape/cdrom driver code.
  *
  *
- *	If action is ide_next, then the rq is queued immediately after
- *	the currently-being-processed-request (if any), and the function
- *	returns without waiting for the new rq to be completed.  As above,
- *	This is VERY DANGEROUS, and is intended for careful use by the
- *	ATAPI tape/cdrom driver code.
- *
  *	If action is ide_end, then the rq is queued at the end of the
  *	If action is ide_end, then the rq is queued at the end of the
  *	request queue, and the function returns immediately without waiting
  *	request queue, and the function returns immediately without waiting
  *	for the new rq to be completed. This is again intended for careful
  *	for the new rq to be completed. This is again intended for careful

+ 4 - 4
drivers/ide/ide-lib.c

@@ -410,10 +410,10 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
 {
 {
 	u64 addr = BLK_BOUNCE_HIGH;	/* dma64_addr_t */
 	u64 addr = BLK_BOUNCE_HIGH;	/* dma64_addr_t */
 
 
-	if (on && drive->media == ide_disk) {
-		if (!PCI_DMA_BUS_IS_PHYS)
-			addr = BLK_BOUNCE_ANY;
-		else if (HWIF(drive)->pci_dev)
+	if (!PCI_DMA_BUS_IS_PHYS) {
+		addr = BLK_BOUNCE_ANY;
+	} else if (on && drive->media == ide_disk) {
+		if (HWIF(drive)->pci_dev)
 			addr = HWIF(drive)->pci_dev->dma_mask;
 			addr = HWIF(drive)->pci_dev->dma_mask;
 	}
 	}
 
 

+ 2 - 5
drivers/ide/ide-tape.c

@@ -4748,8 +4748,8 @@ static ide_proc_entry_t idetape_proc[] = {
 static int ide_tape_probe(struct device *);
 static int ide_tape_probe(struct device *);
 
 
 static ide_driver_t idetape_driver = {
 static ide_driver_t idetape_driver = {
-	.owner			= THIS_MODULE,
 	.gen_driver = {
 	.gen_driver = {
+		.owner		= THIS_MODULE,
 		.name		= "ide-tape",
 		.name		= "ide-tape",
 		.bus		= &ide_bus_type,
 		.bus		= &ide_bus_type,
 		.probe		= ide_tape_probe,
 		.probe		= ide_tape_probe,
@@ -4916,10 +4916,7 @@ static void __exit idetape_exit (void)
 	unregister_chrdev(IDETAPE_MAJOR, "ht");
 	unregister_chrdev(IDETAPE_MAJOR, "ht");
 }
 }
 
 
-/*
- *	idetape_init will register the driver for each tape.
- */
-static int idetape_init (void)
+static int __init idetape_init(void)
 {
 {
 	int error = 1;
 	int error = 1;
 	idetape_sysfs_class = class_create(THIS_MODULE, "ide_tape");
 	idetape_sysfs_class = class_create(THIS_MODULE, "ide_tape");

+ 3 - 24
drivers/ide/ide-taskfile.c

@@ -51,8 +51,6 @@
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/io.h>
 
 
-#define DEBUG_TASKFILE	0	/* unset when fixed */
-
 static void ata_bswap_data (void *buffer, int wcount)
 static void ata_bswap_data (void *buffer, int wcount)
 {
 {
 	u16 *p = buffer;
 	u16 *p = buffer;
@@ -765,9 +763,6 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
 	ide_hwif_t *hwif	= HWIF(drive);
 	ide_hwif_t *hwif	= HWIF(drive);
 	task_struct_t *taskfile	= (task_struct_t *) task->tfRegister;
 	task_struct_t *taskfile	= (task_struct_t *) task->tfRegister;
 	hob_struct_t *hobfile	= (hob_struct_t *) task->hobRegister;
 	hob_struct_t *hobfile	= (hob_struct_t *) task->hobRegister;
-#if DEBUG_TASKFILE
-	u8 status;
-#endif
 
 
 	if (task->data_phase == TASKFILE_MULTI_IN ||
 	if (task->data_phase == TASKFILE_MULTI_IN ||
 	    task->data_phase == TASKFILE_MULTI_OUT) {
 	    task->data_phase == TASKFILE_MULTI_OUT) {
@@ -778,19 +773,13 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
 	}
 	}
 
 
 	/*
 	/*
-	 * (ks) Check taskfile in/out flags.
+	 * (ks) Check taskfile in flags.
 	 * If set, then execute as it is defined.
 	 * If set, then execute as it is defined.
 	 * If not set, then define default settings.
 	 * If not set, then define default settings.
 	 * The default values are:
 	 * The default values are:
-	 *	write and read all taskfile registers (except data) 
-	 *	write and read the hob registers (sector,nsector,lcyl,hcyl)
+	 *	read all taskfile registers (except data)
+	 *	read the hob registers (sector, nsector, lcyl, hcyl)
 	 */
 	 */
-	if (task->tf_out_flags.all == 0) {
-		task->tf_out_flags.all = IDE_TASKFILE_STD_OUT_FLAGS;
-		if (drive->addressing == 1)
-			task->tf_out_flags.all |= (IDE_HOB_STD_OUT_FLAGS << 8);
-        }
-
 	if (task->tf_in_flags.all == 0) {
 	if (task->tf_in_flags.all == 0) {
 		task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
 		task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
 		if (drive->addressing == 1)
 		if (drive->addressing == 1)
@@ -803,16 +792,6 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
 		hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
 		hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
 	SELECT_MASK(drive, 0);
 	SELECT_MASK(drive, 0);
 
 
-#if DEBUG_TASKFILE
-	status = hwif->INB(IDE_STATUS_REG);
-	if (status & 0x80) {
-		printk("flagged_taskfile -> Bad status. Status = %02x. wait 100 usec ...\n", status);
-		udelay(100);
-		status = hwif->INB(IDE_STATUS_REG);
-		printk("flagged_taskfile -> Status = %02x\n", status);
-	}
-#endif
-
 	if (task->tf_out_flags.b.data) {
 	if (task->tf_out_flags.b.data) {
 		u16 data =  taskfile->data + (hobfile->data << 8);
 		u16 data =  taskfile->data + (hobfile->data << 8);
 		hwif->OUTW(data, IDE_DATA_REG);
 		hwif->OUTW(data, IDE_DATA_REG);

+ 0 - 47
drivers/ide/pci/aec62xx.c

@@ -65,23 +65,6 @@ static struct chipset_bus_clock_list_entry aec6xxx_34_base [] = {
 #define BUSCLOCK(D)	\
 #define BUSCLOCK(D)	\
 	((struct chipset_bus_clock_list_entry *) pci_get_drvdata((D)))
 	((struct chipset_bus_clock_list_entry *) pci_get_drvdata((D)))
 
 
-#if 0
-		if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
-			(void) pci_read_config_byte(dev, 0x54, &art);
-			p += sprintf(p, "DMA Mode:       %s(%s)",
-				(c0&0x20)?((art&0x03)?"UDMA":" DMA"):" PIO",
-				(art&0x02)?"2":(art&0x01)?"1":"0");
-			p += sprintf(p, "          %s(%s)",
-				(c0&0x40)?((art&0x0c)?"UDMA":" DMA"):" PIO",
-				(art&0x08)?"2":(art&0x04)?"1":"0");
-			p += sprintf(p, "         %s(%s)",
-				(c1&0x20)?((art&0x30)?"UDMA":" DMA"):" PIO",
-				(art&0x20)?"2":(art&0x10)?"1":"0");
-			p += sprintf(p, "           %s(%s)\n",
-				(c1&0x40)?((art&0xc0)?"UDMA":" DMA"):" PIO",
-				(art&0x80)?"2":(art&0x40)?"1":"0");
-		} else {
-#endif
 
 
 /*
 /*
  * TO DO: active tuning and correction of cards without a bios.
  * TO DO: active tuning and correction of cards without a bios.
@@ -112,13 +95,9 @@ static u8 aec62xx_ratemask (ide_drive_t *drive)
 	switch(hwif->pci_dev->device) {
 	switch(hwif->pci_dev->device) {
 		case PCI_DEVICE_ID_ARTOP_ATP865:
 		case PCI_DEVICE_ID_ARTOP_ATP865:
 		case PCI_DEVICE_ID_ARTOP_ATP865R:
 		case PCI_DEVICE_ID_ARTOP_ATP865R:
-#if 0
-			mode = (hwif->INB(hwif->dma_master) & 0x10) ? 4 : 3;
-#else
 			mode = (hwif->INB(((hwif->channel) ?
 			mode = (hwif->INB(((hwif->channel) ?
 					hwif->mate->dma_status :
 					hwif->mate->dma_status :
 					hwif->dma_status)) & 0x10) ? 4 : 3;
 					hwif->dma_status)) & 0x10) ? 4 : 3;
-#endif
 			break;
 			break;
 		case PCI_DEVICE_ID_ARTOP_ATP860:
 		case PCI_DEVICE_ID_ARTOP_ATP860:
 		case PCI_DEVICE_ID_ARTOP_ATP860R:
 		case PCI_DEVICE_ID_ARTOP_ATP860R:
@@ -263,35 +242,9 @@ static int aec62xx_irq_timeout (ide_drive_t *drive)
 		case PCI_DEVICE_ID_ARTOP_ATP865:
 		case PCI_DEVICE_ID_ARTOP_ATP865:
 		case PCI_DEVICE_ID_ARTOP_ATP865R:
 		case PCI_DEVICE_ID_ARTOP_ATP865R:
 			printk(" AEC62XX time out ");
 			printk(" AEC62XX time out ");
-#if 0
-			{
-				int i = 0;
-				u8 reg49h = 0;
-				pci_read_config_byte(HWIF(drive)->pci_dev, 0x49, &reg49h);
-				for (i=0;i<256;i++)
-					pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h|0x10);
-				pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h & ~0x10);
-			}
-			return 0;
-#endif
 		default:
 		default:
 			break;
 			break;
 	}
 	}
-#if 0
-	{
-		ide_hwif_t *hwif	= HWIF(drive);
-		struct pci_dev *dev	= hwif->pci_dev;
-		u8 tmp1 = 0, tmp2 = 0, mode6 = 0;
-
-		pci_read_config_byte(dev, 0x44, &tmp1);
-		pci_read_config_byte(dev, 0x45, &tmp2);
-		printk(" AEC6280 r44=%x r45=%x ",tmp1,tmp2);
-		mode6 = HWIF(drive)->INB(((hwif->channel) ?
-					   hwif->mate->dma_status :
-					   hwif->dma_status));
-		printk(" AEC6280 133=%x ", (mode6 & 0x10));
-	}
-#endif
 	return 0;
 	return 0;
 }
 }
 
 

+ 7 - 2
drivers/ide/pci/alim15x3.c

@@ -876,10 +876,15 @@ static ide_pci_device_t ali15x3_chipset __devinitdata = {
  
  
 static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
 {
+	static struct pci_device_id ati_rs100[] = {
+		{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100) },
+		{ },
+	};
+
 	ide_pci_device_t *d = &ali15x3_chipset;
 	ide_pci_device_t *d = &ali15x3_chipset;
 
 
-	if(pci_find_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, NULL))
-		printk(KERN_ERR "Warning: ATI Radeon IGP Northbridge is not yet fully tested.\n");
+	if (pci_dev_present(ati_rs100))
+		printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n");
 
 
 #if defined(CONFIG_SPARC64)
 #if defined(CONFIG_SPARC64)
 	d->init_hwif = init_hwif_common_ali15x3;
 	d->init_hwif = init_hwif_common_ali15x3;

+ 2 - 3
drivers/ide/pci/cs5520.c

@@ -222,10 +222,9 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
 
 
 	/* We must not grab the entire device, it has 'ISA' space in its
 	/* We must not grab the entire device, it has 'ISA' space in its
 	   BARS too and we will freak out other bits of the kernel */
 	   BARS too and we will freak out other bits of the kernel */
-	if(pci_enable_device_bars(dev, 1<<2))
-	{
+	if (pci_enable_device_bars(dev, 1<<2)) {
 		printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name);
 		printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name);
-		return 1;
+		return -ENODEV;
 	}
 	}
 	pci_set_master(dev);
 	pci_set_master(dev);
 	if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
 	if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {

+ 7 - 1
drivers/ide/pci/siimage.c

@@ -6,7 +6,13 @@
  *
  *
  *  May be copied or modified under the terms of the GNU General Public License
  *  May be copied or modified under the terms of the GNU General Public License
  *
  *
- *  Documentation available under NDA only
+ *  Documentation for CMD680:
+ *  http://gkernel.sourceforge.net/specs/sii/sii-0680a-v1.31.pdf.bz2
+ *
+ *  Documentation for SiI 3112:
+ *  http://gkernel.sourceforge.net/specs/sii/3112A_SiI-DS-0095-B2.pdf.bz2
+ *
+ *  Errata and other documentation only available under NDA.
  *
  *
  *
  *
  *  FAQ Items:
  *  FAQ Items:

+ 1 - 0
drivers/ide/pci/sis5513.c

@@ -87,6 +87,7 @@ static const struct {
 	u8 chipset_family;
 	u8 chipset_family;
 	u8 flags;
 	u8 flags;
 } SiSHostChipInfo[] = {
 } SiSHostChipInfo[] = {
+	{ "SiS965",	PCI_DEVICE_ID_SI_965,	ATA_133  },
 	{ "SiS745",	PCI_DEVICE_ID_SI_745,	ATA_100  },
 	{ "SiS745",	PCI_DEVICE_ID_SI_745,	ATA_100  },
 	{ "SiS735",	PCI_DEVICE_ID_SI_735,	ATA_100  },
 	{ "SiS735",	PCI_DEVICE_ID_SI_735,	ATA_100  },
 	{ "SiS733",	PCI_DEVICE_ID_SI_733,	ATA_100  },
 	{ "SiS733",	PCI_DEVICE_ID_SI_733,	ATA_100  },

+ 135 - 272
drivers/ide/pci/via82cxxx.c

@@ -79,6 +79,7 @@ static struct via_isa_bridge {
 	u8 rev_max;
 	u8 rev_max;
 	u16 flags;
 	u16 flags;
 } via_isa_bridges[] = {
 } via_isa_bridges[] = {
+	{ "vt6410",	PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8235",	PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8235",	PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8233a",	PCI_DEVICE_ID_VIA_8233A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8233a",	PCI_DEVICE_ID_VIA_8233A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
@@ -100,185 +101,14 @@ static struct via_isa_bridge {
 	{ NULL }
 	{ NULL }
 };
 };
 
 
-static struct via_isa_bridge *via_config;
-static unsigned int via_80w;
 static unsigned int via_clock;
 static unsigned int via_clock;
 static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
 static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
 
 
-/*
- * VIA /proc entry.
- */
-
-#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
-
-#include <linux/stat.h>
-#include <linux/proc_fs.h>
-
-static u8 via_proc = 0;
-static unsigned long via_base;
-static struct pci_dev *bmide_dev, *isa_dev;
-
-static char *via_control3[] = { "No limit", "64", "128", "192" };
-
-#define via_print(format, arg...) p += sprintf(p, format "\n" , ## arg)
-#define via_print_drive(name, format, arg...)\
-	p += sprintf(p, name); for (i = 0; i < 4; i++) p += sprintf(p, format, ## arg); p += sprintf(p, "\n");
-
-
-/**
- *	via_get_info		-	generate via /proc file 
- *	@buffer: buffer for data
- *	@addr: set to start of data to use
- *	@offset: current file offset
- *	@count: size of read
- *
- *	Fills in buffer with the debugging/configuration information for
- *	the VIA chipset tuning and attached drives
- */
- 
-static int via_get_info(char *buffer, char **addr, off_t offset, int count)
+struct via82cxxx_dev
 {
 {
-	int speed[4], cycle[4], setup[4], active[4], recover[4], den[4],
-		 uen[4], udma[4], umul[4], active8b[4], recover8b[4];
-	struct pci_dev *dev = bmide_dev;
-	unsigned int v, u, i;
-	int len;
-	u16 c, w;
-	u8 t, x;
-	char *p = buffer;
-
-	via_print("----------VIA BusMastering IDE Configuration"
-		"----------------");
-
-	via_print("Driver Version:                     3.38");
-	via_print("South Bridge:                       VIA %s",
-		via_config->name);
-
-	pci_read_config_byte(isa_dev, PCI_REVISION_ID, &t);
-	pci_read_config_byte(dev, PCI_REVISION_ID, &x);
-	via_print("Revision:                           ISA %#x IDE %#x", t, x);
-	via_print("Highest DMA rate:                   %s",
-		via_dma[via_config->flags & VIA_UDMA]);
-
-	via_print("BM-DMA base:                        %#lx", via_base);
-	via_print("PCI clock:                          %d.%dMHz",
-		via_clock / 1000, via_clock / 100 % 10);
-
-	pci_read_config_byte(dev, VIA_MISC_1, &t);
-	via_print("Master Read  Cycle IRDY:            %dws",
-		(t & 64) >> 6);
-	via_print("Master Write Cycle IRDY:            %dws",
-		(t & 32) >> 5);
-	via_print("BM IDE Status Register Read Retry:  %s",
-		(t & 8) ? "yes" : "no");
-
-	pci_read_config_byte(dev, VIA_MISC_3, &t);
-	via_print("Max DRDY Pulse Width:               %s%s",
-		via_control3[(t & 0x03)], (t & 0x03) ? " PCI clocks" : "");
-
-	via_print("-----------------------Primary IDE"
-		"-------Secondary IDE------");
-	via_print("Read DMA FIFO flush:   %10s%20s",
-		(t & 0x80) ? "yes" : "no", (t & 0x40) ? "yes" : "no");
-	via_print("End Sector FIFO flush: %10s%20s",
-		(t & 0x20) ? "yes" : "no", (t & 0x10) ? "yes" : "no");
-
-	pci_read_config_byte(dev, VIA_IDE_CONFIG, &t);
-	via_print("Prefetch Buffer:       %10s%20s",
-		(t & 0x80) ? "yes" : "no", (t & 0x20) ? "yes" : "no");
-	via_print("Post Write Buffer:     %10s%20s",
-		(t & 0x40) ? "yes" : "no", (t & 0x10) ? "yes" : "no");
-
-	pci_read_config_byte(dev, VIA_IDE_ENABLE, &t);
-	via_print("Enabled:               %10s%20s",
-		(t & 0x02) ? "yes" : "no", (t & 0x01) ? "yes" : "no");
-
-	c = inb(via_base + 0x02) | (inb(via_base + 0x0a) << 8);
-	via_print("Simplex only:          %10s%20s",
-		(c & 0x80) ? "yes" : "no", (c & 0x8000) ? "yes" : "no");
-
-	via_print("Cable Type:            %10s%20s",
-		(via_80w & 1) ? "80w" : "40w", (via_80w & 2) ? "80w" : "40w");
-
-	via_print("-------------------drive0----drive1"
-		"----drive2----drive3-----");
-
-	pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t);
-	pci_read_config_dword(dev, VIA_DRIVE_TIMING, &v);
-	pci_read_config_word(dev, VIA_8BIT_TIMING, &w);
-
-	if (via_config->flags & VIA_UDMA)
-		pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
-	else u = 0;
-
-	for (i = 0; i < 4; i++) {
-
-		setup[i]     = ((t >> ((3 - i) << 1)) & 0x3) + 1;
-		recover8b[i] = ((w >> ((1 - (i >> 1)) << 3)) & 0xf) + 1;
-		active8b[i]  = ((w >> (((1 - (i >> 1)) << 3) + 4)) & 0xf) + 1;
-		active[i]    = ((v >> (((3 - i) << 3) + 4)) & 0xf) + 1;
-		recover[i]   = ((v >> ((3 - i) << 3)) & 0xf) + 1;
-		udma[i]      = ((u >> ((3 - i) << 3)) & 0x7) + 2;
-		umul[i]      = ((u >> (((3 - i) & 2) << 3)) & 0x8) ? 1 : 2;
-		uen[i]       = ((u >> ((3 - i) << 3)) & 0x20);
-		den[i]       = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2));
-
-		speed[i] = 2 * via_clock / (active[i] + recover[i]);
-		cycle[i] = 1000000 * (active[i] + recover[i]) / via_clock;
-
-		if (!uen[i] || !den[i])
-			continue;
-
-		switch (via_config->flags & VIA_UDMA) {
-
-			case VIA_UDMA_33:
-				speed[i] = 2 * via_clock / udma[i];
-				cycle[i] = 1000000 * udma[i] / via_clock;
-				break;
-
-			case VIA_UDMA_66:
-				speed[i] = 4 * via_clock / (udma[i] * umul[i]);
-				cycle[i] = 500000 * (udma[i] * umul[i]) / via_clock;
-				break;
-
-			case VIA_UDMA_100:
-				speed[i] = 6 * via_clock / udma[i];
-				cycle[i] = 333333 * udma[i] / via_clock;
-				break;
-
-			case VIA_UDMA_133:
-				speed[i] = 8 * via_clock / udma[i];
-				cycle[i] = 250000 * udma[i] / via_clock;
-				break;
-		}
-	}
-
-	via_print_drive("Transfer Mode: ", "%10s",
-		den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO");
-
-	via_print_drive("Address Setup: ", "%8dns",
-		1000000 * setup[i] / via_clock);
-	via_print_drive("Cmd Active:    ", "%8dns",
-		1000000 * active8b[i] / via_clock);
-	via_print_drive("Cmd Recovery:  ", "%8dns",
-		1000000 * recover8b[i] / via_clock);
-	via_print_drive("Data Active:   ", "%8dns",
-		1000000 * active[i] / via_clock);
-	via_print_drive("Data Recovery: ", "%8dns",
-		1000000 * recover[i] / via_clock);
-	via_print_drive("Cycle Time:    ", "%8dns",
-		cycle[i]);
-	via_print_drive("Transfer Rate: ", "%4d.%dMB/s",
-		speed[i] / 1000, speed[i] / 100 % 10);
-
-	/* hoping it is less than 4K... */
-	len = (p - buffer) - offset;
-	*addr = buffer + offset;
-
-	return len > count ? count : len;
-}
-
-#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS */
+	struct via_isa_bridge *via_config;
+	unsigned int via_80w;
+};
 
 
 /**
 /**
  *	via_set_speed			-	write timing registers
  *	via_set_speed			-	write timing registers
@@ -289,11 +119,13 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count)
  *	via_set_speed writes timing values to the chipset registers
  *	via_set_speed writes timing values to the chipset registers
  */
  */
 
 
-static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing)
+static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
 {
 {
+	struct pci_dev *dev = hwif->pci_dev;
+	struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif);
 	u8 t;
 	u8 t;
 
 
-	if (~via_config->flags & VIA_BAD_AST) {
+	if (~vdev->via_config->flags & VIA_BAD_AST) {
 		pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t);
 		pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t);
 		t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
 		t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
 		pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t);
 		pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t);
@@ -305,7 +137,7 @@ static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing)
 	pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn),
 	pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn),
 		((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1));
 		((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1));
 
 
-	switch (via_config->flags & VIA_UDMA) {
+	switch (vdev->via_config->flags & VIA_UDMA) {
 		case VIA_UDMA_33:  t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
 		case VIA_UDMA_33:  t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
 		case VIA_UDMA_66:  t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break;
 		case VIA_UDMA_66:  t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break;
 		case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
 		case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
@@ -329,6 +161,7 @@ static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing)
 static int via_set_drive(ide_drive_t *drive, u8 speed)
 static int via_set_drive(ide_drive_t *drive, u8 speed)
 {
 {
 	ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
 	ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
+	struct via82cxxx_dev *vdev = ide_get_hwifdata(drive->hwif);
 	struct ide_timing t, p;
 	struct ide_timing t, p;
 	unsigned int T, UT;
 	unsigned int T, UT;
 
 
@@ -337,7 +170,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
 
 
 	T = 1000000000 / via_clock;
 	T = 1000000000 / via_clock;
 
 
-	switch (via_config->flags & VIA_UDMA) {
+	switch (vdev->via_config->flags & VIA_UDMA) {
 		case VIA_UDMA_33:   UT = T;   break;
 		case VIA_UDMA_33:   UT = T;   break;
 		case VIA_UDMA_66:   UT = T/2; break;
 		case VIA_UDMA_66:   UT = T/2; break;
 		case VIA_UDMA_100:  UT = T/3; break;
 		case VIA_UDMA_100:  UT = T/3; break;
@@ -352,7 +185,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
 		ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
 		ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
 	}
 	}
 
 
-	via_set_speed(HWIF(drive)->pci_dev, drive->dn, &t);
+	via_set_speed(HWIF(drive), drive->dn, &t);
 
 
 	if (!drive->init_speed)
 	if (!drive->init_speed)
 		drive->init_speed = speed;
 		drive->init_speed = speed;
@@ -390,20 +223,41 @@ static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio)
  
  
 static int via82cxxx_ide_dma_check (ide_drive_t *drive)
 static int via82cxxx_ide_dma_check (ide_drive_t *drive)
 {
 {
-	u16 w80 = HWIF(drive)->udma_four;
+	ide_hwif_t *hwif = HWIF(drive);
+	struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif);
+	u16 w80 = hwif->udma_four;
 
 
 	u16 speed = ide_find_best_mode(drive,
 	u16 speed = ide_find_best_mode(drive,
 		XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
 		XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
-		(via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
-		(w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
-		(w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
-		(w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
+		(vdev->via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
+		(w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
+		(w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
+		(w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
 
 
 	via_set_drive(drive, speed);
 	via_set_drive(drive, speed);
 
 
 	if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
 	if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
-		return HWIF(drive)->ide_dma_on(drive);
-	return HWIF(drive)->ide_dma_off_quietly(drive);
+		return hwif->ide_dma_on(drive);
+	return hwif->ide_dma_off_quietly(drive);
+}
+
+static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
+{
+	struct via_isa_bridge *via_config;
+	u8 t;
+
+	for (via_config = via_isa_bridges; via_config->id; via_config++)
+		if ((*isa = pci_find_device(PCI_VENDOR_ID_VIA +
+			!!(via_config->flags & VIA_BAD_ID),
+			via_config->id, NULL))) {
+
+			pci_read_config_byte(*isa, PCI_REVISION_ID, &t);
+			if (t >= via_config->rev_min &&
+			    t <= via_config->rev_max)
+				break;
+		}
+
+	return via_config;
 }
 }
 
 
 /**
 /**
@@ -418,82 +272,28 @@ static int via82cxxx_ide_dma_check (ide_drive_t *drive)
 static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name)
 static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name)
 {
 {
 	struct pci_dev *isa = NULL;
 	struct pci_dev *isa = NULL;
+	struct via_isa_bridge *via_config;
 	u8 t, v;
 	u8 t, v;
 	unsigned int u;
 	unsigned int u;
-	int i;
 
 
 	/*
 	/*
 	 * Find the ISA bridge to see how good the IDE is.
 	 * Find the ISA bridge to see how good the IDE is.
 	 */
 	 */
-
-	for (via_config = via_isa_bridges; via_config->id; via_config++)
-		if ((isa = pci_find_device(PCI_VENDOR_ID_VIA +
-			!!(via_config->flags & VIA_BAD_ID),
-			via_config->id, NULL))) {
-
-			pci_read_config_byte(isa, PCI_REVISION_ID, &t);
-			if (t >= via_config->rev_min &&
-			    t <= via_config->rev_max)
-				break;
-		}
-
+	via_config = via_config_find(&isa);
 	if (!via_config->id) {
 	if (!via_config->id) {
 		printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n");
 		printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n");
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 
 
 	/*
 	/*
-	 * Check 80-wire cable presence and setup Clk66.
+	 * Setup or disable Clk66 if appropriate
 	 */
 	 */
 
 
-	switch (via_config->flags & VIA_UDMA) {
-
-		case VIA_UDMA_66:
-			/* Enable Clk66 */
-			pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
-			pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008);
-			for (i = 24; i >= 0; i -= 8)
-				if (((u >> (i & 16)) & 8) &&
-				    ((u >> i) & 0x20) &&
-				     (((u >> i) & 7) < 2)) {
-					/*
-					 * 2x PCI clock and
-					 * UDMA w/ < 3T/cycle
-					 */
-					via_80w |= (1 << (1 - (i >> 4)));
-				}
-			break;
-
-		case VIA_UDMA_100:
-			pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
-			for (i = 24; i >= 0; i -= 8)
-				if (((u >> i) & 0x10) ||
-				    (((u >> i) & 0x20) &&
-				     (((u >> i) & 7) < 4))) {
-					/* BIOS 80-wire bit or
-					 * UDMA w/ < 60ns/cycle
-					 */
-					via_80w |= (1 << (1 - (i >> 4)));
-				}
-			break;
-
-		case VIA_UDMA_133:
-			pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
-			for (i = 24; i >= 0; i -= 8)
-				if (((u >> i) & 0x10) ||
-				    (((u >> i) & 0x20) &&
-				     (((u >> i) & 7) < 6))) {
-					/* BIOS 80-wire bit or
-					 * UDMA w/ < 60ns/cycle
-					 */
-					via_80w |= (1 << (1 - (i >> 4)));
-				}
-			break;
-
-	}
-
-	/* Disable Clk66 */
-	if (via_config->flags & VIA_BAD_CLK66) {
+	if ((via_config->flags & VIA_UDMA) == VIA_UDMA_66) {
+		/* Enable Clk66 */
+		pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
+		pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008);
+	} else if (via_config->flags & VIA_BAD_CLK66) {
 		/* Would cause trouble on 596a and 686 */
 		/* Would cause trouble on 596a and 686 */
 		pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
 		pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
 		pci_write_config_dword(dev, VIA_UDMA_TIMING, u & ~0x80008);
 		pci_write_config_dword(dev, VIA_UDMA_TIMING, u & ~0x80008);
@@ -560,26 +360,78 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
 		via_dma[via_config->flags & VIA_UDMA],
 		via_dma[via_config->flags & VIA_UDMA],
 		pci_name(dev));
 		pci_name(dev));
 
 
-	/*
-	 * Setup /proc/ide/via entry.
-	 */
+	return 0;
+}
+
+/*
+ * Check and handle 80-wire cable presence
+ */
+static void __devinit via_cable_detect(struct pci_dev *dev, struct via82cxxx_dev *vdev)
+{
+	unsigned int u;
+	int i;
+	pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
+
+	switch (vdev->via_config->flags & VIA_UDMA) {
+
+		case VIA_UDMA_66:
+			for (i = 24; i >= 0; i -= 8)
+				if (((u >> (i & 16)) & 8) &&
+				    ((u >> i) & 0x20) &&
+				     (((u >> i) & 7) < 2)) {
+					/*
+					 * 2x PCI clock and
+					 * UDMA w/ < 3T/cycle
+					 */
+					vdev->via_80w |= (1 << (1 - (i >> 4)));
+				}
+			break;
+
+		case VIA_UDMA_100:
+			for (i = 24; i >= 0; i -= 8)
+				if (((u >> i) & 0x10) ||
+				    (((u >> i) & 0x20) &&
+				     (((u >> i) & 7) < 4))) {
+					/* BIOS 80-wire bit or
+					 * UDMA w/ < 60ns/cycle
+					 */
+					vdev->via_80w |= (1 << (1 - (i >> 4)));
+				}
+			break;
+
+		case VIA_UDMA_133:
+			for (i = 24; i >= 0; i -= 8)
+				if (((u >> i) & 0x10) ||
+				    (((u >> i) & 0x20) &&
+				     (((u >> i) & 7) < 6))) {
+					/* BIOS 80-wire bit or
+					 * UDMA w/ < 60ns/cycle
+					 */
+					vdev->via_80w |= (1 << (1 - (i >> 4)));
+				}
+			break;
 
 
-#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
-	if (!via_proc) {
-		via_base = pci_resource_start(dev, 4);
-		bmide_dev = dev;
-		isa_dev = isa;
-		ide_pci_create_host_proc("via", via_get_info);
-		via_proc = 1;
 	}
 	}
-#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS */
-	return 0;
 }
 }
 
 
 static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
 static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
 {
 {
+	struct via82cxxx_dev *vdev = kmalloc(sizeof(struct via82cxxx_dev),
+		GFP_KERNEL);
+	struct pci_dev *isa = NULL;
 	int i;
 	int i;
 
 
+	if (vdev == NULL) {
+		printk(KERN_ERR "VP_IDE: out of memory :(\n");
+		return;
+	}
+
+	memset(vdev, 0, sizeof(struct via82cxxx_dev));
+	ide_set_hwifdata(hwif, vdev);
+
+	vdev->via_config = via_config_find(&isa);
+	via_cable_detect(hwif->pci_dev, vdev);
+
 	hwif->autodma = 0;
 	hwif->autodma = 0;
 
 
 	hwif->tuneproc = &via82cxxx_tune_drive;
 	hwif->tuneproc = &via82cxxx_tune_drive;
@@ -594,7 +446,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
 
 
 	for (i = 0; i < 2; i++) {
 	for (i = 0; i < 2; i++) {
 		hwif->drives[i].io_32bit = 1;
 		hwif->drives[i].io_32bit = 1;
-		hwif->drives[i].unmask = (via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
+		hwif->drives[i].unmask = (vdev->via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
 		hwif->drives[i].autotune = 1;
 		hwif->drives[i].autotune = 1;
 		hwif->drives[i].dn = hwif->channel * 2 + i;
 		hwif->drives[i].dn = hwif->channel * 2 + i;
 	}
 	}
@@ -608,7 +460,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
 	hwif->swdma_mask = 0x07;
 	hwif->swdma_mask = 0x07;
 
 
 	if (!hwif->udma_four)
 	if (!hwif->udma_four)
-		hwif->udma_four = (via_80w >> hwif->channel) & 1;
+		hwif->udma_four = (vdev->via_80w >> hwif->channel) & 1;
 	hwif->ide_dma_check = &via82cxxx_ide_dma_check;
 	hwif->ide_dma_check = &via82cxxx_ide_dma_check;
 	if (!noautodma)
 	if (!noautodma)
 		hwif->autodma = 1;
 		hwif->autodma = 1;
@@ -616,24 +468,35 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
 	hwif->drives[1].autodma = hwif->autodma;
 	hwif->drives[1].autodma = hwif->autodma;
 }
 }
 
 
-static ide_pci_device_t via82cxxx_chipset __devinitdata = {
-	.name		= "VP_IDE",
-	.init_chipset	= init_chipset_via82cxxx,
-	.init_hwif	= init_hwif_via82cxxx,
-	.channels	= 2,
-	.autodma	= NOAUTODMA,
-	.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
-	.bootable	= ON_BOARD,
+static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
+	{	/* 0 */
+		.name		= "VP_IDE",
+		.init_chipset	= init_chipset_via82cxxx,
+		.init_hwif	= init_hwif_via82cxxx,
+		.channels	= 2,
+		.autodma	= NOAUTODMA,
+		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
+		.bootable	= ON_BOARD
+	},{	/* 1 */
+		.name		= "VP_IDE",
+		.init_chipset	= init_chipset_via82cxxx,
+		.init_hwif	= init_hwif_via82cxxx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+		.bootable	= ON_BOARD,
+	}
 };
 };
 
 
 static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
 {
-	return ide_setup_pci_device(dev, &via82cxxx_chipset);
+	return ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]);
 }
 }
 
 
 static struct pci_device_id via_pci_tbl[] = {
 static struct pci_device_id via_pci_tbl[] = {
 	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_6410,     PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
 	{ 0, },
 	{ 0, },
 };
 };
 MODULE_DEVICE_TABLE(pci, via_pci_tbl);
 MODULE_DEVICE_TABLE(pci, via_pci_tbl);

+ 0 - 14
drivers/ide/ppc/pmac.c

@@ -1401,20 +1401,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
 	/* We probe the hwif now */
 	/* We probe the hwif now */
 	probe_hwif_init(hwif);
 	probe_hwif_init(hwif);
 
 
-	/* The code IDE code will have set hwif->present if we have devices attached,
-	 * if we don't, the discard the interface except if we are on a media bay slot
-	 */
-	if (!hwif->present && !pmif->mediabay) {
-		printk(KERN_INFO "ide%d: Bus empty, interface released.\n",
-			hwif->index);
-		default_hwif_iops(hwif);
-		for (i = IDE_DATA_OFFSET; i <= IDE_CONTROL_OFFSET; ++i)
-			hwif->io_ports[i] = 0;
-		hwif->chipset = ide_unknown;
-		hwif->noprobe = 1;
-		return -ENODEV;
-	}
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 1
drivers/ide/setup-pci.c

@@ -787,7 +787,7 @@ static int pre_init = 1;		/* Before first ordered IDE scan */
 static LIST_HEAD(ide_pci_drivers);
 static LIST_HEAD(ide_pci_drivers);
 
 
 /*
 /*
- *	__ide_register_pci_driver	-	attach IDE driver
+ *	__ide_pci_register_driver	-	attach IDE driver
  *	@driver: pci driver
  *	@driver: pci driver
  *	@module: owner module of the driver
  *	@module: owner module of the driver
  *
  *

+ 1 - 1
drivers/infiniband/core/user_mad.c

@@ -312,7 +312,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
 	int ret, length, hdr_len, copy_offset;
 	int ret, length, hdr_len, copy_offset;
 	int rmpp_active = 0;
 	int rmpp_active = 0;
 
 
-	if (count < sizeof (struct ib_user_mad))
+	if (count < sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	length = count - sizeof (struct ib_user_mad);
 	length = count - sizeof (struct ib_user_mad);

+ 18 - 19
drivers/infiniband/hw/mthca/mthca_qp.c

@@ -730,14 +730,15 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
 	}
 	}
 
 
 	if (attr_mask & IB_QP_ACCESS_FLAGS) {
 	if (attr_mask & IB_QP_ACCESS_FLAGS) {
+		qp_context->params2 |=
+			cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE ?
+				    MTHCA_QP_BIT_RWE : 0);
+
 		/*
 		/*
-		 * Only enable RDMA/atomics if we have responder
-		 * resources set to a non-zero value.
+		 * Only enable RDMA reads and atomics if we have
+		 * responder resources set to a non-zero value.
 		 */
 		 */
 		if (qp->resp_depth) {
 		if (qp->resp_depth) {
-			qp_context->params2 |=
-				cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE ?
-					    MTHCA_QP_BIT_RWE : 0);
 			qp_context->params2 |=
 			qp_context->params2 |=
 				cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_READ ?
 				cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_READ ?
 					    MTHCA_QP_BIT_RRE : 0);
 					    MTHCA_QP_BIT_RRE : 0);
@@ -759,22 +760,19 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
 		if (qp->resp_depth && !attr->max_dest_rd_atomic) {
 		if (qp->resp_depth && !attr->max_dest_rd_atomic) {
 			/*
 			/*
 			 * Lowering our responder resources to zero.
 			 * Lowering our responder resources to zero.
-			 * Turn off RDMA/atomics as responder.
-			 * (RWE/RRE/RAE in params2 already zero)
+			 * Turn off reads RDMA and atomics as responder.
+			 * (RRE/RAE in params2 already zero)
 			 */
 			 */
-			qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |
-								MTHCA_QP_OPTPAR_RRE |
+			qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE |
 								MTHCA_QP_OPTPAR_RAE);
 								MTHCA_QP_OPTPAR_RAE);
 		}
 		}
 
 
 		if (!qp->resp_depth && attr->max_dest_rd_atomic) {
 		if (!qp->resp_depth && attr->max_dest_rd_atomic) {
 			/*
 			/*
 			 * Increasing our responder resources from
 			 * Increasing our responder resources from
-			 * zero.  Turn on RDMA/atomics as appropriate.
+			 * zero.  Turn on RDMA reads and atomics as
+			 * appropriate.
 			 */
 			 */
-			qp_context->params2 |=
-				cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_WRITE ?
-					    MTHCA_QP_BIT_RWE : 0);
 			qp_context->params2 |=
 			qp_context->params2 |=
 				cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_READ ?
 				cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_READ ?
 					    MTHCA_QP_BIT_RRE : 0);
 					    MTHCA_QP_BIT_RRE : 0);
@@ -782,8 +780,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
 				cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_ATOMIC ?
 				cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_ATOMIC ?
 					    MTHCA_QP_BIT_RAE : 0);
 					    MTHCA_QP_BIT_RAE : 0);
 
 
-			qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |
-								MTHCA_QP_OPTPAR_RRE |
+			qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE |
 								MTHCA_QP_OPTPAR_RAE);
 								MTHCA_QP_OPTPAR_RAE);
 		}
 		}
 
 
@@ -921,10 +918,12 @@ static void mthca_adjust_qp_caps(struct mthca_dev *dev,
         else
         else
 		qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE;
 		qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE;
 
 
-	qp->sq.max_gs = max_data_size / sizeof (struct mthca_data_seg);
-	qp->rq.max_gs = (min(dev->limits.max_desc_sz, 1 << qp->rq.wqe_shift) -
-			sizeof (struct mthca_next_seg)) /
-			sizeof (struct mthca_data_seg);
+	qp->sq.max_gs = min_t(int, dev->limits.max_sg,
+			      max_data_size / sizeof (struct mthca_data_seg));
+	qp->rq.max_gs = min_t(int, dev->limits.max_sg,
+			       (min(dev->limits.max_desc_sz, 1 << qp->rq.wqe_shift) -
+				sizeof (struct mthca_next_seg)) /
+			       sizeof (struct mthca_data_seg));
 }
 }
 
 
 /*
 /*

+ 11 - 6
drivers/infiniband/ulp/srp/ib_srp.c

@@ -802,13 +802,21 @@ static int srp_post_recv(struct srp_target_port *target)
 
 
 /*
 /*
  * Must be called with target->scsi_host->host_lock held to protect
  * Must be called with target->scsi_host->host_lock held to protect
- * req_lim and tx_head.
+ * req_lim and tx_head.  Lock cannot be dropped between call here and
+ * call to __srp_post_send().
  */
  */
 static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target)
 static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target)
 {
 {
 	if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE)
 	if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE)
 		return NULL;
 		return NULL;
 
 
+	if (unlikely(target->req_lim < 1)) {
+		if (printk_ratelimit())
+			printk(KERN_DEBUG PFX "Target has req_lim %d\n",
+			       target->req_lim);
+		return NULL;
+	}
+
 	return target->tx_ring[target->tx_head & SRP_SQ_SIZE];
 	return target->tx_ring[target->tx_head & SRP_SQ_SIZE];
 }
 }
 
 
@@ -823,11 +831,6 @@ static int __srp_post_send(struct srp_target_port *target,
 	struct ib_send_wr wr, *bad_wr;
 	struct ib_send_wr wr, *bad_wr;
 	int ret = 0;
 	int ret = 0;
 
 
-	if (target->req_lim < 1) {
-		printk(KERN_ERR PFX "Target has req_lim %d\n", target->req_lim);
-		return -EAGAIN;
-	}
-
 	list.addr   = iu->dma;
 	list.addr   = iu->dma;
 	list.length = len;
 	list.length = len;
 	list.lkey   = target->srp_host->mr->lkey;
 	list.lkey   = target->srp_host->mr->lkey;
@@ -1417,6 +1420,8 @@ static ssize_t srp_create_target(struct class_device *class_dev,
 	if (!target_host)
 	if (!target_host)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
+	target_host->max_lun = SRP_MAX_LUN;
+
 	target = host_to_target(target_host);
 	target = host_to_target(target_host);
 	memset(target, 0, sizeof *target);
 	memset(target, 0, sizeof *target);
 
 

+ 1 - 0
drivers/infiniband/ulp/srp/ib_srp.h

@@ -54,6 +54,7 @@ enum {
 	SRP_PORT_REDIRECT	= 1,
 	SRP_PORT_REDIRECT	= 1,
 	SRP_DLID_REDIRECT	= 2,
 	SRP_DLID_REDIRECT	= 2,
 
 
+	SRP_MAX_LUN		= 512,
 	SRP_MAX_IU_LEN		= 256,
 	SRP_MAX_IU_LEN		= 256,
 
 
 	SRP_RQ_SHIFT    	= 6,
 	SRP_RQ_SHIFT    	= 6,

+ 9 - 3
drivers/input/gameport/gameport.c

@@ -339,14 +339,20 @@ static struct gameport_event *gameport_get_event(void)
 	return event;
 	return event;
 }
 }
 
 
-static void gameport_handle_events(void)
+static void gameport_handle_event(void)
 {
 {
 	struct gameport_event *event;
 	struct gameport_event *event;
 	struct gameport_driver *gameport_drv;
 	struct gameport_driver *gameport_drv;
 
 
 	down(&gameport_sem);
 	down(&gameport_sem);
 
 
-	while ((event = gameport_get_event())) {
+	/*
+	 * Note that we handle only one event here to give swsusp
+	 * a chance to freeze kgameportd thread. Gameport events
+	 * should be pretty rare so we are not concerned about
+	 * taking performance hit.
+	 */
+	if ((event = gameport_get_event())) {
 
 
 		switch (event->type) {
 		switch (event->type) {
 			case GAMEPORT_REGISTER_PORT:
 			case GAMEPORT_REGISTER_PORT:
@@ -433,7 +439,7 @@ static struct gameport *gameport_get_pending_child(struct gameport *parent)
 static int gameport_thread(void *nothing)
 static int gameport_thread(void *nothing)
 {
 {
 	do {
 	do {
-		gameport_handle_events();
+		gameport_handle_event();
 		wait_event_interruptible(gameport_wait,
 		wait_event_interruptible(gameport_wait,
 			kthread_should_stop() || !list_empty(&gameport_event_list));
 			kthread_should_stop() || !list_empty(&gameport_event_list));
 		try_to_freeze();
 		try_to_freeze();

+ 36 - 27
drivers/input/input.c

@@ -536,7 +536,7 @@ static struct attribute *input_dev_attrs[] = {
 	NULL
 	NULL
 };
 };
 
 
-static struct attribute_group input_dev_group = {
+static struct attribute_group input_dev_attr_group = {
 	.attrs	= input_dev_attrs,
 	.attrs	= input_dev_attrs,
 };
 };
 
 
@@ -717,35 +717,14 @@ struct input_dev *input_allocate_device(void)
 	return dev;
 	return dev;
 }
 }
 
 
-static void input_register_classdevice(struct input_dev *dev)
-{
-	static atomic_t input_no = ATOMIC_INIT(0);
-	const char *path;
-
-	__module_get(THIS_MODULE);
-
-	dev->dev = dev->cdev.dev;
-
-	snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
-		 "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
-
-	path = kobject_get_path(&dev->cdev.class->subsys.kset.kobj, GFP_KERNEL);
-	printk(KERN_INFO "input: %s as %s/%s\n",
-		dev->name ? dev->name : "Unspecified device",
-		path ? path : "", dev->cdev.class_id);
-	kfree(path);
-
-	class_device_add(&dev->cdev);
-	sysfs_create_group(&dev->cdev.kobj, &input_dev_group);
-	sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group);
-	sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
-}
-
 int input_register_device(struct input_dev *dev)
 int input_register_device(struct input_dev *dev)
 {
 {
+	static atomic_t input_no = ATOMIC_INIT(0);
 	struct input_handle *handle;
 	struct input_handle *handle;
 	struct input_handler *handler;
 	struct input_handler *handler;
 	struct input_device_id *id;
 	struct input_device_id *id;
+	const char *path;
+	int error;
 
 
 	if (!dev->dynalloc) {
 	if (!dev->dynalloc) {
 		printk(KERN_WARNING "input: device %s is statically allocated, will not register\n"
 		printk(KERN_WARNING "input: device %s is statically allocated, will not register\n"
@@ -773,7 +752,32 @@ int input_register_device(struct input_dev *dev)
 	INIT_LIST_HEAD(&dev->h_list);
 	INIT_LIST_HEAD(&dev->h_list);
 	list_add_tail(&dev->node, &input_dev_list);
 	list_add_tail(&dev->node, &input_dev_list);
 
 
-	input_register_classdevice(dev);
+	dev->cdev.class = &input_class;
+	snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
+		 "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
+
+	error = class_device_add(&dev->cdev);
+	if (error)
+		return error;
+
+	error = sysfs_create_group(&dev->cdev.kobj, &input_dev_attr_group);
+	if (error)
+		goto fail1;
+
+	error = sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group);
+	if (error)
+		goto fail2;
+
+	error = sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
+	if (error)
+		goto fail3;
+
+	__module_get(THIS_MODULE);
+
+	path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
+	printk(KERN_INFO "input: %s as %s\n",
+		dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
+	kfree(path);
 
 
 	list_for_each_entry(handler, &input_handler_list, node)
 	list_for_each_entry(handler, &input_handler_list, node)
 		if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
 		if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
@@ -784,6 +788,11 @@ int input_register_device(struct input_dev *dev)
 	input_wakeup_procfs_readers();
 	input_wakeup_procfs_readers();
 
 
 	return 0;
 	return 0;
+
+ fail3:	sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
+ fail2:	sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group);
+ fail1:	class_device_del(&dev->cdev);
+	return error;
 }
 }
 
 
 void input_unregister_device(struct input_dev *dev)
 void input_unregister_device(struct input_dev *dev)
@@ -805,7 +814,7 @@ void input_unregister_device(struct input_dev *dev)
 
 
 	sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
 	sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
 	sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
 	sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
-	sysfs_remove_group(&dev->cdev.kobj, &input_dev_group);
+	sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group);
 	class_device_unregister(&dev->cdev);
 	class_device_unregister(&dev->cdev);
 
 
 	input_wakeup_procfs_readers();
 	input_wakeup_procfs_readers();

+ 68 - 31
drivers/input/keyboard/atkbd.c

@@ -166,6 +166,9 @@ static unsigned char atkbd_unxlate_table[128] = {
 
 
 #define ATKBD_SPECIAL		248
 #define ATKBD_SPECIAL		248
 
 
+#define ATKBD_LED_EVENT_BIT	0
+#define ATKBD_REP_EVENT_BIT	1
+
 static struct {
 static struct {
 	unsigned char keycode;
 	unsigned char keycode;
 	unsigned char set2;
 	unsigned char set2;
@@ -211,6 +214,10 @@ struct atkbd {
 	unsigned char err_xl;
 	unsigned char err_xl;
 	unsigned int last;
 	unsigned int last;
 	unsigned long time;
 	unsigned long time;
+
+	struct work_struct event_work;
+	struct semaphore event_sem;
+	unsigned long event_mask;
 };
 };
 
 
 static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
 static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
@@ -424,58 +431,86 @@ out:
 }
 }
 
 
 /*
 /*
- * Event callback from the input module. Events that change the state of
- * the hardware are processed here.
+ * atkbd_event_work() is used to complete processing of events that
+ * can not be processed by input_event() which is often called from
+ * interrupt context.
  */
  */
 
 
-static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+static void atkbd_event_work(void *data)
 {
 {
-	struct atkbd *atkbd = dev->private;
 	const short period[32] =
 	const short period[32] =
 		{ 33,  37,  42,  46,  50,  54,  58,  63,  67,  75,  83,  92, 100, 109, 116, 125,
 		{ 33,  37,  42,  46,  50,  54,  58,  63,  67,  75,  83,  92, 100, 109, 116, 125,
 		 133, 149, 167, 182, 200, 217, 232, 250, 270, 303, 333, 370, 400, 435, 470, 500 };
 		 133, 149, 167, 182, 200, 217, 232, 250, 270, 303, 333, 370, 400, 435, 470, 500 };
 	const short delay[4] =
 	const short delay[4] =
 		{ 250, 500, 750, 1000 };
 		{ 250, 500, 750, 1000 };
+
+	struct atkbd *atkbd = data;
+	struct input_dev *dev = atkbd->dev;
 	unsigned char param[2];
 	unsigned char param[2];
 	int i, j;
 	int i, j;
 
 
+	down(&atkbd->event_sem);
+
+	if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) {
+		param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0)
+			 | (test_bit(LED_NUML,    dev->led) ? 2 : 0)
+			 | (test_bit(LED_CAPSL,   dev->led) ? 4 : 0);
+		ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS);
+
+		if (atkbd->extra) {
+			param[0] = 0;
+			param[1] = (test_bit(LED_COMPOSE, dev->led) ? 0x01 : 0)
+				 | (test_bit(LED_SLEEP,   dev->led) ? 0x02 : 0)
+				 | (test_bit(LED_SUSPEND, dev->led) ? 0x04 : 0)
+				 | (test_bit(LED_MISC,    dev->led) ? 0x10 : 0)
+				 | (test_bit(LED_MUTE,    dev->led) ? 0x20 : 0);
+			ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS);
+		}
+	}
+
+	if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask)) {
+		i = j = 0;
+		while (i < 31 && period[i] < dev->rep[REP_PERIOD])
+			i++;
+		while (j < 3 && delay[j] < dev->rep[REP_DELAY])
+			j++;
+		dev->rep[REP_PERIOD] = period[i];
+		dev->rep[REP_DELAY] = delay[j];
+		param[0] = i | (j << 5);
+		ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP);
+	}
+
+	up(&atkbd->event_sem);
+}
+
+/*
+ * Event callback from the input module. Events that change the state of
+ * the hardware are processed here. If action can not be performed in
+ * interrupt context it is offloaded to atkbd_event_work.
+ */
+
+static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+{
+	struct atkbd *atkbd = dev->private;
+
 	if (!atkbd->write)
 	if (!atkbd->write)
 		return -1;
 		return -1;
 
 
 	switch (type) {
 	switch (type) {
 
 
 		case EV_LED:
 		case EV_LED:
-
-			param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0)
-			         | (test_bit(LED_NUML,    dev->led) ? 2 : 0)
-			         | (test_bit(LED_CAPSL,   dev->led) ? 4 : 0);
-		        ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS);
-
-			if (atkbd->extra) {
-				param[0] = 0;
-				param[1] = (test_bit(LED_COMPOSE, dev->led) ? 0x01 : 0)
-					 | (test_bit(LED_SLEEP,   dev->led) ? 0x02 : 0)
-					 | (test_bit(LED_SUSPEND, dev->led) ? 0x04 : 0)
-				         | (test_bit(LED_MISC,    dev->led) ? 0x10 : 0)
-				         | (test_bit(LED_MUTE,    dev->led) ? 0x20 : 0);
-				ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS);
-			}
-
+			set_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask);
+			wmb();
+			schedule_work(&atkbd->event_work);
 			return 0;
 			return 0;
 
 
 		case EV_REP:
 		case EV_REP:
 
 
-			if (atkbd->softrepeat) return 0;
-
-			i = j = 0;
-			while (i < 31 && period[i] < dev->rep[REP_PERIOD])
-				i++;
-			while (j < 3 && delay[j] < dev->rep[REP_DELAY])
-				j++;
-			dev->rep[REP_PERIOD] = period[i];
-			dev->rep[REP_DELAY] = delay[j];
-			param[0] = i | (j << 5);
-			ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP);
+			if (!atkbd->softrepeat) {
+				set_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask);
+				wmb();
+				schedule_work(&atkbd->event_work);
+			}
 
 
 			return 0;
 			return 0;
 	}
 	}
@@ -810,6 +845,8 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
 
 
 	atkbd->dev = dev;
 	atkbd->dev = dev;
 	ps2_init(&atkbd->ps2dev, serio);
 	ps2_init(&atkbd->ps2dev, serio);
+	INIT_WORK(&atkbd->event_work, atkbd_event_work, atkbd);
+	init_MUTEX(&atkbd->event_sem);
 
 
 	switch (serio->id.type) {
 	switch (serio->id.type) {
 
 

+ 10 - 0
drivers/input/misc/Kconfig

@@ -40,6 +40,16 @@ config INPUT_M68K_BEEP
 	tristate "M68k Beeper support"
 	tristate "M68k Beeper support"
 	depends on M68K
 	depends on M68K
 
 
+config INPUT_WISTRON_BTNS
+	tristate "x86 Wistron laptop button interface"
+	depends on X86 && !X86_64
+	help
+	  Say Y here for support of Winstron laptop button interface, used on
+	  laptops of various brands, including Acer and Fujitsu-Siemens.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called wistron_btns.
+
 config INPUT_UINPUT
 config INPUT_UINPUT
 	tristate "User level driver support"
 	tristate "User level driver support"
 	help
 	help

+ 1 - 0
drivers/input/misc/Makefile

@@ -9,4 +9,5 @@ obj-$(CONFIG_INPUT_PCSPKR)		+= pcspkr.o
 obj-$(CONFIG_INPUT_M68K_BEEP)		+= m68kspkr.o
 obj-$(CONFIG_INPUT_M68K_BEEP)		+= m68kspkr.o
 obj-$(CONFIG_INPUT_98SPKR)		+= 98spkr.o
 obj-$(CONFIG_INPUT_98SPKR)		+= 98spkr.o
 obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
 obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
+obj-$(CONFIG_INPUT_WISTRON_BTNS)	+= wistron_btns.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o

+ 170 - 155
drivers/input/misc/uinput.c

@@ -92,24 +92,19 @@ static void uinput_request_done(struct uinput_device *udev, struct uinput_reques
 {
 {
 	/* Mark slot as available */
 	/* Mark slot as available */
 	udev->requests[request->id] = NULL;
 	udev->requests[request->id] = NULL;
-	wake_up_interruptible(&udev->requests_waitq);
+	wake_up(&udev->requests_waitq);
 
 
 	complete(&request->done);
 	complete(&request->done);
 }
 }
 
 
 static int uinput_request_submit(struct input_dev *dev, struct uinput_request *request)
 static int uinput_request_submit(struct input_dev *dev, struct uinput_request *request)
 {
 {
-	int retval;
-
 	/* Tell our userspace app about this new request by queueing an input event */
 	/* Tell our userspace app about this new request by queueing an input event */
 	uinput_dev_event(dev, EV_UINPUT, request->code, request->id);
 	uinput_dev_event(dev, EV_UINPUT, request->code, request->id);
 
 
 	/* Wait for the request to complete */
 	/* Wait for the request to complete */
-	retval = wait_for_completion_interruptible(&request->done);
-	if (!retval)
-		retval = request->retval;
-
-	return retval;
+	wait_for_completion(&request->done);
+	return request->retval;
 }
 }
 
 
 static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect)
 static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect)
@@ -152,67 +147,62 @@ static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
 	return retval;
 	return retval;
 }
 }
 
 
-static int uinput_create_device(struct uinput_device *udev)
+static void uinput_destroy_device(struct uinput_device *udev)
 {
 {
-	if (!udev->dev->name) {
-		printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME);
-		return -EINVAL;
+	const char *name, *phys;
+
+	if (udev->dev) {
+		name = udev->dev->name;
+		phys = udev->dev->phys;
+		if (udev->state == UIST_CREATED)
+			input_unregister_device(udev->dev);
+		else
+			input_free_device(udev->dev);
+		kfree(name);
+		kfree(phys);
+		udev->dev = NULL;
 	}
 	}
 
 
-	udev->dev->event = uinput_dev_event;
-	udev->dev->upload_effect = uinput_dev_upload_effect;
-	udev->dev->erase_effect = uinput_dev_erase_effect;
-	udev->dev->private = udev;
-
-	init_waitqueue_head(&udev->waitq);
-
-	input_register_device(udev->dev);
-
-	set_bit(UIST_CREATED, &udev->state);
-
-	return 0;
+	udev->state = UIST_NEW_DEVICE;
 }
 }
 
 
-static int uinput_destroy_device(struct uinput_device *udev)
+static int uinput_create_device(struct uinput_device *udev)
 {
 {
-	if (!test_bit(UIST_CREATED, &udev->state)) {
-		printk(KERN_WARNING "%s: create the device first\n", UINPUT_NAME);
+	int error;
+
+	if (udev->state != UIST_SETUP_COMPLETE) {
+		printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	input_unregister_device(udev->dev);
+	error = input_register_device(udev->dev);
+	if (error) {
+		uinput_destroy_device(udev);
+		return error;
+	}
 
 
-	clear_bit(UIST_CREATED, &udev->state);
+	udev->state = UIST_CREATED;
 
 
 	return 0;
 	return 0;
 }
 }
 
 
 static int uinput_open(struct inode *inode, struct file *file)
 static int uinput_open(struct inode *inode, struct file *file)
 {
 {
-	struct uinput_device	*newdev;
-	struct input_dev	*newinput;
+	struct uinput_device *newdev;
 
 
-	newdev = kmalloc(sizeof(struct uinput_device), GFP_KERNEL);
+	newdev = kzalloc(sizeof(struct uinput_device), GFP_KERNEL);
 	if (!newdev)
 	if (!newdev)
-		goto error;
-	memset(newdev, 0, sizeof(struct uinput_device));
+		return -ENOMEM;
+
+	init_MUTEX(&newdev->sem);
 	spin_lock_init(&newdev->requests_lock);
 	spin_lock_init(&newdev->requests_lock);
 	init_waitqueue_head(&newdev->requests_waitq);
 	init_waitqueue_head(&newdev->requests_waitq);
-
-	newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
-	if (!newinput)
-		goto cleanup;
-	memset(newinput, 0, sizeof(struct input_dev));
-
-	newdev->dev = newinput;
+	init_waitqueue_head(&newdev->waitq);
+	newdev->state = UIST_NEW_DEVICE;
 
 
 	file->private_data = newdev;
 	file->private_data = newdev;
 
 
 	return 0;
 	return 0;
-cleanup:
-	kfree(newdev);
-error:
-	return -ENOMEM;
 }
 }
 
 
 static int uinput_validate_absbits(struct input_dev *dev)
 static int uinput_validate_absbits(struct input_dev *dev)
@@ -246,34 +236,55 @@ static int uinput_validate_absbits(struct input_dev *dev)
 	return retval;
 	return retval;
 }
 }
 
 
-static int uinput_alloc_device(struct file *file, const char __user *buffer, size_t count)
+static int uinput_allocate_device(struct uinput_device *udev)
+{
+	udev->dev = input_allocate_device();
+	if (!udev->dev)
+		return -ENOMEM;
+
+	udev->dev->event = uinput_dev_event;
+	udev->dev->upload_effect = uinput_dev_upload_effect;
+	udev->dev->erase_effect = uinput_dev_erase_effect;
+	udev->dev->private = udev;
+
+	return 0;
+}
+
+static int uinput_setup_device(struct uinput_device *udev, const char __user *buffer, size_t count)
 {
 {
 	struct uinput_user_dev	*user_dev;
 	struct uinput_user_dev	*user_dev;
 	struct input_dev	*dev;
 	struct input_dev	*dev;
-	struct uinput_device	*udev;
 	char			*name;
 	char			*name;
 	int			size;
 	int			size;
 	int			retval;
 	int			retval;
 
 
-	retval = count;
+	if (count != sizeof(struct uinput_user_dev))
+		return -EINVAL;
+
+	if (!udev->dev) {
+		retval = uinput_allocate_device(udev);
+		if (retval)
+			return retval;
+	}
 
 
-	udev = file->private_data;
 	dev = udev->dev;
 	dev = udev->dev;
 
 
 	user_dev = kmalloc(sizeof(struct uinput_user_dev), GFP_KERNEL);
 	user_dev = kmalloc(sizeof(struct uinput_user_dev), GFP_KERNEL);
-	if (!user_dev) {
-		retval = -ENOMEM;
-		goto exit;
-	}
+	if (!user_dev)
+		return -ENOMEM;
 
 
 	if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) {
 	if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) {
 		retval = -EFAULT;
 		retval = -EFAULT;
 		goto exit;
 		goto exit;
 	}
 	}
 
 
-	kfree(dev->name);
-
 	size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
 	size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
+	if (!size) {
+		retval = -EINVAL;
+		goto exit;
+	}
+
+	kfree(dev->name);
 	dev->name = name = kmalloc(size, GFP_KERNEL);
 	dev->name = name = kmalloc(size, GFP_KERNEL);
 	if (!name) {
 	if (!name) {
 		retval = -ENOMEM;
 		retval = -ENOMEM;
@@ -296,32 +307,50 @@ static int uinput_alloc_device(struct file *file, const char __user *buffer, siz
 	/* check if absmin/absmax/absfuzz/absflat are filled as
 	/* check if absmin/absmax/absfuzz/absflat are filled as
 	 * told in Documentation/input/input-programming.txt */
 	 * told in Documentation/input/input-programming.txt */
 	if (test_bit(EV_ABS, dev->evbit)) {
 	if (test_bit(EV_ABS, dev->evbit)) {
-		int err = uinput_validate_absbits(dev);
-		if (err < 0) {
-			retval = err;
-			kfree(dev->name);
-		}
+		retval = uinput_validate_absbits(dev);
+		if (retval < 0)
+			goto exit;
 	}
 	}
 
 
-exit:
+	udev->state = UIST_SETUP_COMPLETE;
+	retval = count;
+
+ exit:
 	kfree(user_dev);
 	kfree(user_dev);
 	return retval;
 	return retval;
 }
 }
 
 
+static inline ssize_t uinput_inject_event(struct uinput_device *udev, const char __user *buffer, size_t count)
+{
+	struct input_event ev;
+
+	if (count != sizeof(struct input_event))
+		return -EINVAL;
+
+	if (copy_from_user(&ev, buffer, sizeof(struct input_event)))
+		return -EFAULT;
+
+	input_event(udev->dev, ev.type, ev.code, ev.value);
+
+	return sizeof(struct input_event);
+}
+
 static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
 {
 	struct uinput_device *udev = file->private_data;
 	struct uinput_device *udev = file->private_data;
+	int retval;
+
+	retval = down_interruptible(&udev->sem);
+	if (retval)
+		return retval;
 
 
-	if (test_bit(UIST_CREATED, &udev->state)) {
-		struct input_event	ev;
+	retval = udev->state == UIST_CREATED ?
+			uinput_inject_event(udev, buffer, count) :
+			uinput_setup_device(udev, buffer, count);
 
 
-		if (copy_from_user(&ev, buffer, sizeof(struct input_event)))
-			return -EFAULT;
-		input_event(udev->dev, ev.type, ev.code, ev.value);
-	} else
-		count = uinput_alloc_device(file, buffer, count);
+	up(&udev->sem);
 
 
-	return count;
+	return retval;
 }
 }
 
 
 static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
@@ -329,28 +358,38 @@ static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count,
 	struct uinput_device *udev = file->private_data;
 	struct uinput_device *udev = file->private_data;
 	int retval = 0;
 	int retval = 0;
 
 
-	if (!test_bit(UIST_CREATED, &udev->state))
+	if (udev->state != UIST_CREATED)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	if (udev->head == udev->tail && (file->f_flags & O_NONBLOCK))
 	if (udev->head == udev->tail && (file->f_flags & O_NONBLOCK))
 		return -EAGAIN;
 		return -EAGAIN;
 
 
 	retval = wait_event_interruptible(udev->waitq,
 	retval = wait_event_interruptible(udev->waitq,
-			udev->head != udev->tail || !test_bit(UIST_CREATED, &udev->state));
+			udev->head != udev->tail || udev->state != UIST_CREATED);
 	if (retval)
 	if (retval)
 		return retval;
 		return retval;
 
 
-	if (!test_bit(UIST_CREATED, &udev->state))
-		return -ENODEV;
+	retval = down_interruptible(&udev->sem);
+	if (retval)
+		return retval;
 
 
-	while ((udev->head != udev->tail) &&
-	    (retval + sizeof(struct input_event) <= count)) {
-		if (copy_to_user(buffer + retval, &udev->buff[udev->tail], sizeof(struct input_event)))
-			return -EFAULT;
+	if (udev->state != UIST_CREATED) {
+		retval = -ENODEV;
+		goto out;
+	}
+
+	while (udev->head != udev->tail && retval + sizeof(struct input_event) <= count) {
+		if (copy_to_user(buffer + retval, &udev->buff[udev->tail], sizeof(struct input_event))) {
+			retval = -EFAULT;
+			goto out;
+		}
 		udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE;
 		udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE;
 		retval += sizeof(struct input_event);
 		retval += sizeof(struct input_event);
 	}
 	}
 
 
+ out:
+	up(&udev->sem);
+
 	return retval;
 	return retval;
 }
 }
 
 
@@ -366,28 +405,30 @@ static unsigned int uinput_poll(struct file *file, poll_table *wait)
 	return 0;
 	return 0;
 }
 }
 
 
-static int uinput_burn_device(struct uinput_device *udev)
+static int uinput_release(struct inode *inode, struct file *file)
 {
 {
-	if (test_bit(UIST_CREATED, &udev->state))
-		uinput_destroy_device(udev);
+	struct uinput_device *udev = file->private_data;
 
 
-	kfree(udev->dev->name);
-	kfree(udev->dev->phys);
-	kfree(udev->dev);
+	uinput_destroy_device(udev);
 	kfree(udev);
 	kfree(udev);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int uinput_close(struct inode *inode, struct file *file)
+#define uinput_set_bit(_arg, _bit, _max)		\
+({							\
+	int __ret = 0;					\
+	if (udev->state == UIST_CREATED)		\
+		__ret =  -EINVAL;			\
+	else if ((_arg) > (_max))			\
+		__ret = -EINVAL;			\
+	else set_bit((_arg), udev->dev->_bit);		\
+	__ret;						\
+})
+
+static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 {
-	uinput_burn_device(file->private_data);
-	return 0;
-}
-
-static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	int			retval = 0;
+	int			retval;
 	struct uinput_device	*udev;
 	struct uinput_device	*udev;
 	void __user             *p = (void __user *)arg;
 	void __user             *p = (void __user *)arg;
 	struct uinput_ff_upload ff_up;
 	struct uinput_ff_upload ff_up;
@@ -398,19 +439,14 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 
 
 	udev = file->private_data;
 	udev = file->private_data;
 
 
-	/* device attributes can not be changed after the device is created */
-	switch (cmd) {
-		case UI_SET_EVBIT:
-		case UI_SET_KEYBIT:
-		case UI_SET_RELBIT:
-		case UI_SET_ABSBIT:
-		case UI_SET_MSCBIT:
-		case UI_SET_LEDBIT:
-		case UI_SET_SNDBIT:
-		case UI_SET_FFBIT:
-		case UI_SET_PHYS:
-			if (test_bit(UIST_CREATED, &udev->state))
-				return -EINVAL;
+	retval = down_interruptible(&udev->sem);
+	if (retval)
+		return retval;
+
+	if (!udev->dev) {
+		retval = uinput_allocate_device(udev);
+		if (retval)
+			goto out;
 	}
 	}
 
 
 	switch (cmd) {
 	switch (cmd) {
@@ -419,74 +455,50 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 			break;
 			break;
 
 
 		case UI_DEV_DESTROY:
 		case UI_DEV_DESTROY:
-			retval = uinput_destroy_device(udev);
+			uinput_destroy_device(udev);
 			break;
 			break;
 
 
 		case UI_SET_EVBIT:
 		case UI_SET_EVBIT:
-			if (arg > EV_MAX) {
-				retval = -EINVAL;
-				break;
-			}
-			set_bit(arg, udev->dev->evbit);
+			retval = uinput_set_bit(arg, evbit, EV_MAX);
 			break;
 			break;
 
 
 		case UI_SET_KEYBIT:
 		case UI_SET_KEYBIT:
-			if (arg > KEY_MAX) {
-				retval = -EINVAL;
-				break;
-			}
-			set_bit(arg, udev->dev->keybit);
+			retval = uinput_set_bit(arg, keybit, KEY_MAX);
 			break;
 			break;
 
 
 		case UI_SET_RELBIT:
 		case UI_SET_RELBIT:
-			if (arg > REL_MAX) {
-				retval = -EINVAL;
-				break;
-			}
-			set_bit(arg, udev->dev->relbit);
+			retval = uinput_set_bit(arg, relbit, REL_MAX);
 			break;
 			break;
 
 
 		case UI_SET_ABSBIT:
 		case UI_SET_ABSBIT:
-			if (arg > ABS_MAX) {
-				retval = -EINVAL;
-				break;
-			}
-			set_bit(arg, udev->dev->absbit);
+			retval = uinput_set_bit(arg, absbit, ABS_MAX);
 			break;
 			break;
 
 
 		case UI_SET_MSCBIT:
 		case UI_SET_MSCBIT:
-			if (arg > MSC_MAX) {
-				retval = -EINVAL;
-				break;
-			}
-			set_bit(arg, udev->dev->mscbit);
+			retval = uinput_set_bit(arg, mscbit, MSC_MAX);
 			break;
 			break;
 
 
 		case UI_SET_LEDBIT:
 		case UI_SET_LEDBIT:
-			if (arg > LED_MAX) {
-				retval = -EINVAL;
-				break;
-			}
-			set_bit(arg, udev->dev->ledbit);
+			retval = uinput_set_bit(arg, ledbit, LED_MAX);
 			break;
 			break;
 
 
 		case UI_SET_SNDBIT:
 		case UI_SET_SNDBIT:
-			if (arg > SND_MAX) {
-				retval = -EINVAL;
-				break;
-			}
-			set_bit(arg, udev->dev->sndbit);
+			retval = uinput_set_bit(arg, sndbit, SND_MAX);
 			break;
 			break;
 
 
 		case UI_SET_FFBIT:
 		case UI_SET_FFBIT:
-			if (arg > FF_MAX) {
-				retval = -EINVAL;
-				break;
-			}
-			set_bit(arg, udev->dev->ffbit);
+			retval = uinput_set_bit(arg, ffbit, FF_MAX);
+			break;
+
+		case UI_SET_SWBIT:
+			retval = uinput_set_bit(arg, swbit, SW_MAX);
 			break;
 			break;
 
 
 		case UI_SET_PHYS:
 		case UI_SET_PHYS:
+			if (udev->state == UIST_CREATED) {
+				retval = -EINVAL;
+				goto out;
+			}
 			length = strnlen_user(p, 1024);
 			length = strnlen_user(p, 1024);
 			if (length <= 0) {
 			if (length <= 0) {
 				retval = -EFAULT;
 				retval = -EFAULT;
@@ -575,23 +587,26 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 		default:
 		default:
 			retval = -EINVAL;
 			retval = -EINVAL;
 	}
 	}
+
+ out:
+	up(&udev->sem);
 	return retval;
 	return retval;
 }
 }
 
 
 static struct file_operations uinput_fops = {
 static struct file_operations uinput_fops = {
-	.owner =	THIS_MODULE,
-	.open =		uinput_open,
-	.release =	uinput_close,
-	.read =		uinput_read,
-	.write =	uinput_write,
-	.poll =		uinput_poll,
-	.ioctl =	uinput_ioctl,
+	.owner		= THIS_MODULE,
+	.open		= uinput_open,
+	.release	= uinput_release,
+	.read		= uinput_read,
+	.write		= uinput_write,
+	.poll		= uinput_poll,
+	.unlocked_ioctl	= uinput_ioctl,
 };
 };
 
 
 static struct miscdevice uinput_misc = {
 static struct miscdevice uinput_misc = {
-	.fops =		&uinput_fops,
-	.minor =	UINPUT_MINOR,
-	.name =		UINPUT_NAME,
+	.fops		= &uinput_fops,
+	.minor		= UINPUT_MINOR,
+	.name		= UINPUT_NAME,
 };
 };
 
 
 static int __init uinput_init(void)
 static int __init uinput_init(void)

+ 561 - 0
drivers/input/misc/wistron_btns.c

@@ -0,0 +1,561 @@
+/*
+ * Wistron laptop button driver
+ * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
+ * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
+ * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
+ *
+ * You can redistribute and/or modify this program under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <asm/io.h>
+#include <linux/dmi.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mc146818rtc.h>
+#include <linux/module.h>
+#include <linux/preempt.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+
+/*
+ * Number of attempts to read data from queue per poll;
+ * the queue can hold up to 31 entries
+ */
+#define MAX_POLL_ITERATIONS 64
+
+#define POLL_FREQUENCY 10 /* Number of polls per second */
+
+#if POLL_FREQUENCY > HZ
+#error "POLL_FREQUENCY too high"
+#endif
+
+/* BIOS subsystem IDs */
+#define WIFI		0x35
+#define BLUETOOTH	0x34
+
+MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>");
+MODULE_DESCRIPTION("Wistron laptop button driver");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("0.1");
+
+static int force; /* = 0; */
+module_param(force, bool, 0);
+MODULE_PARM_DESC(force, "Load even if computer is not in database");
+
+static char *keymap_name; /* = NULL; */
+module_param_named(keymap, keymap_name, charp, 0);
+MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected");
+
+static struct platform_device *wistron_device;
+
+ /* BIOS interface implementation */
+
+static void __iomem *bios_entry_point; /* BIOS routine entry point */
+static void __iomem *bios_code_map_base;
+static void __iomem *bios_data_map_base;
+
+static u8 cmos_address;
+
+struct regs {
+	u32 eax, ebx, ecx;
+};
+
+static void call_bios(struct regs *regs)
+{
+	unsigned long flags;
+
+	preempt_disable();
+	local_irq_save(flags);
+	asm volatile ("pushl %%ebp;"
+		      "movl %7, %%ebp;"
+		      "call *%6;"
+		      "popl %%ebp"
+		      : "=a" (regs->eax), "=b" (regs->ebx), "=c" (regs->ecx)
+		      : "0" (regs->eax), "1" (regs->ebx), "2" (regs->ecx),
+			"m" (bios_entry_point), "m" (bios_data_map_base)
+		      : "edx", "edi", "esi", "memory");
+	local_irq_restore(flags);
+	preempt_enable();
+}
+
+static size_t __init locate_wistron_bios(void __iomem *base)
+{
+	static const unsigned char __initdata signature[] =
+		{ 0x42, 0x21, 0x55, 0x30 };
+	size_t offset;
+
+	for (offset = 0; offset < 0x10000; offset += 0x10) {
+		if (check_signature(base + offset, signature,
+				    sizeof(signature)) != 0)
+			return offset;
+	}
+	return -1;
+}
+
+static int __init map_bios(void)
+{
+	void __iomem *base;
+	size_t offset;
+	u32 entry_point;
+
+	base = ioremap(0xF0000, 0x10000); /* Can't fail */
+	offset = locate_wistron_bios(base);
+	if (offset < 0) {
+		printk(KERN_ERR "wistron_btns: BIOS entry point not found\n");
+		iounmap(base);
+		return -ENODEV;
+	}
+
+	entry_point = readl(base + offset + 5);
+	printk(KERN_DEBUG
+		"wistron_btns: BIOS signature found at %p, entry point %08X\n",
+		base + offset, entry_point);
+
+	if (entry_point >= 0xF0000) {
+		bios_code_map_base = base;
+		bios_entry_point = bios_code_map_base + (entry_point & 0xFFFF);
+	} else {
+		iounmap(base);
+		bios_code_map_base = ioremap(entry_point & ~0x3FFF, 0x4000);
+		if (bios_code_map_base == NULL) {
+			printk(KERN_ERR
+				"wistron_btns: Can't map BIOS code at %08X\n",
+				entry_point & ~0x3FFF);
+			goto err;
+		}
+		bios_entry_point = bios_code_map_base + (entry_point & 0x3FFF);
+	}
+	/* The Windows driver maps 0x10000 bytes, we keep only one page... */
+	bios_data_map_base = ioremap(0x400, 0xc00);
+	if (bios_data_map_base == NULL) {
+		printk(KERN_ERR "wistron_btns: Can't map BIOS data\n");
+		goto err_code;
+	}
+	return 0;
+
+err_code:
+	iounmap(bios_code_map_base);
+err:
+	return -ENOMEM;
+}
+
+static inline void unmap_bios(void)
+{
+	iounmap(bios_code_map_base);
+	iounmap(bios_data_map_base);
+}
+
+ /* BIOS calls */
+
+static u16 bios_pop_queue(void)
+{
+	struct regs regs;
+
+	memset(&regs, 0, sizeof (regs));
+	regs.eax = 0x9610;
+	regs.ebx = 0x061C;
+	regs.ecx = 0x0000;
+	call_bios(&regs);
+
+	return regs.eax;
+}
+
+static void __init bios_attach(void)
+{
+	struct regs regs;
+
+	memset(&regs, 0, sizeof (regs));
+	regs.eax = 0x9610;
+	regs.ebx = 0x012E;
+	call_bios(&regs);
+}
+
+static void bios_detach(void)
+{
+	struct regs regs;
+
+	memset(&regs, 0, sizeof (regs));
+	regs.eax = 0x9610;
+	regs.ebx = 0x002E;
+	call_bios(&regs);
+}
+
+static u8 __init bios_get_cmos_address(void)
+{
+	struct regs regs;
+
+	memset(&regs, 0, sizeof (regs));
+	regs.eax = 0x9610;
+	regs.ebx = 0x051C;
+	call_bios(&regs);
+
+	return regs.ecx;
+}
+
+static u16 __init bios_get_default_setting(u8 subsys)
+{
+	struct regs regs;
+
+	memset(&regs, 0, sizeof (regs));
+	regs.eax = 0x9610;
+	regs.ebx = 0x0200 | subsys;
+	call_bios(&regs);
+
+	return regs.eax;
+}
+
+static void bios_set_state(u8 subsys, int enable)
+{
+	struct regs regs;
+
+	memset(&regs, 0, sizeof (regs));
+	regs.eax = 0x9610;
+	regs.ebx = (enable ? 0x0100 : 0x0000) | subsys;
+	call_bios(&regs);
+}
+
+/* Hardware database */
+
+struct key_entry {
+	char type;		/* See KE_* below */
+	u8 code;
+	unsigned keycode;	/* For KE_KEY */
+};
+
+enum { KE_END, KE_KEY, KE_WIFI, KE_BLUETOOTH };
+
+static const struct key_entry *keymap; /* = NULL; Current key map */
+static int have_wifi;
+static int have_bluetooth;
+
+static int __init dmi_matched(struct dmi_system_id *dmi)
+{
+	const struct key_entry *key;
+
+	keymap = dmi->driver_data;
+	for (key = keymap; key->type != KE_END; key++) {
+		if (key->type == KE_WIFI) {
+			have_wifi = 1;
+			break;
+		} else if (key->type == KE_BLUETOOTH) {
+			have_bluetooth = 1;
+			break;
+		}
+	}
+	return 1;
+}
+
+static struct key_entry keymap_empty[] = {
+	{ KE_END, 0 }
+};
+
+static struct key_entry keymap_fs_amilo_pro_v2000[] = {
+	{ KE_KEY,  0x01, KEY_HELP },
+	{ KE_KEY,  0x11, KEY_PROG1 },
+	{ KE_KEY,  0x12, KEY_PROG2 },
+	{ KE_WIFI, 0x30, 0 },
+	{ KE_KEY,  0x31, KEY_MAIL },
+	{ KE_KEY,  0x36, KEY_WWW },
+	{ KE_END,  0 }
+};
+
+static struct key_entry keymap_wistron_ms2141[] = {
+	{ KE_KEY,  0x11, KEY_PROG1 },
+	{ KE_KEY,  0x12, KEY_PROG2 },
+	{ KE_WIFI, 0x30, 0 },
+	{ KE_KEY,  0x22, KEY_REWIND },
+	{ KE_KEY,  0x23, KEY_FORWARD },
+	{ KE_KEY,  0x24, KEY_PLAYPAUSE },
+	{ KE_KEY,  0x25, KEY_STOPCD },
+	{ KE_KEY,  0x31, KEY_MAIL },
+	{ KE_KEY,  0x36, KEY_WWW },
+	{ KE_END,  0 }
+};
+
+static struct key_entry keymap_acer_aspire_1500[] = {
+	{ KE_KEY, 0x11, KEY_PROG1 },
+	{ KE_KEY, 0x12, KEY_PROG2 },
+	{ KE_WIFI, 0x30, 0 },
+	{ KE_KEY, 0x31, KEY_MAIL },
+	{ KE_KEY, 0x36, KEY_WWW },
+	{ KE_BLUETOOTH, 0x44, 0 },
+	{ KE_END, 0 }
+};
+
+/*
+ * If your machine is not here (which is currently rather likely), please send
+ * a list of buttons and their key codes (reported when loading this module
+ * with force=1) and the output of dmidecode to $MODULE_AUTHOR.
+ */
+static struct dmi_system_id dmi_ids[] = {
+	{
+		.callback = dmi_matched,
+		.ident = "Fujitsu-Siemens Amilo Pro V2000",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2000"),
+		},
+		.driver_data = keymap_fs_amilo_pro_v2000
+	},
+	{
+		.callback = dmi_matched,
+		.ident = "Acer Aspire 1500",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"),
+		},
+		.driver_data = keymap_acer_aspire_1500
+	},
+	{ 0, }
+};
+
+static int __init select_keymap(void)
+{
+	if (keymap_name != NULL) {
+		if (strcmp (keymap_name, "1557/MS2141") == 0)
+			keymap = keymap_wistron_ms2141;
+		else {
+			printk(KERN_ERR "wistron_btns: Keymap unknown\n");
+			return -EINVAL;
+		}
+	}
+	dmi_check_system(dmi_ids);
+	if (keymap == NULL) {
+		if (!force) {
+			printk(KERN_ERR "wistron_btns: System unknown\n");
+			return -ENODEV;
+		}
+		keymap = keymap_empty;
+	}
+	return 0;
+}
+
+ /* Input layer interface */
+
+static struct input_dev *input_dev;
+
+static int __init setup_input_dev(void)
+{
+	const struct key_entry *key;
+	int error;
+
+	input_dev = input_allocate_device();
+	if (!input_dev)
+		return -ENOMEM;
+
+	input_dev->name = "Wistron laptop buttons";
+	input_dev->phys = "wistron/input0";
+	input_dev->id.bustype = BUS_HOST;
+	input_dev->cdev.dev = &wistron_device->dev;
+
+	for (key = keymap; key->type != KE_END; key++) {
+		if (key->type == KE_KEY) {
+			input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY);
+			set_bit(key->keycode, input_dev->keybit);
+		}
+	}
+
+	error = input_register_device(input_dev);
+	if (error) {
+		input_free_device(input_dev);
+		return error;
+	}
+
+	return 0;
+}
+
+static void report_key(unsigned keycode)
+{
+	input_report_key(input_dev, keycode, 1);
+	input_sync(input_dev);
+	input_report_key(input_dev, keycode, 0);
+	input_sync(input_dev);
+}
+
+ /* Driver core */
+
+static int wifi_enabled;
+static int bluetooth_enabled;
+
+static void poll_bios(unsigned long);
+
+static struct timer_list poll_timer = TIMER_INITIALIZER(poll_bios, 0, 0);
+
+static void handle_key(u8 code)
+{
+	const struct key_entry *key;
+
+	for (key = keymap; key->type != KE_END; key++) {
+		if (code == key->code) {
+			switch (key->type) {
+			case KE_KEY:
+				report_key(key->keycode);
+				break;
+
+			case KE_WIFI:
+				if (have_wifi) {
+					wifi_enabled = !wifi_enabled;
+					bios_set_state(WIFI, wifi_enabled);
+				}
+				break;
+
+			case KE_BLUETOOTH:
+				if (have_bluetooth) {
+					bluetooth_enabled = !bluetooth_enabled;
+					bios_set_state(BLUETOOTH, bluetooth_enabled);
+				}
+				break;
+
+			case KE_END:
+			default:
+				BUG();
+			}
+			return;
+		}
+	}
+	printk(KERN_NOTICE "wistron_btns: Unknown key code %02X\n", code);
+}
+
+static void poll_bios(unsigned long discard)
+{
+	u8 qlen;
+	u16 val;
+
+	for (;;) {
+		qlen = CMOS_READ(cmos_address);
+		if (qlen == 0)
+			break;
+		val = bios_pop_queue();
+		if (val != 0 && !discard)
+			handle_key((u8)val);
+	}
+
+	mod_timer(&poll_timer, jiffies + HZ / POLL_FREQUENCY);
+}
+
+static int wistron_suspend(struct platform_device *dev, pm_message_t state)
+{
+	del_timer_sync(&poll_timer);
+
+	if (have_wifi)
+		bios_set_state(WIFI, 0);
+
+	if (have_bluetooth)
+		bios_set_state(BLUETOOTH, 0);
+
+	return 0;
+}
+
+static int wistron_resume(struct platform_device *dev)
+{
+	if (have_wifi)
+		bios_set_state(WIFI, wifi_enabled);
+
+	if (have_bluetooth)
+		bios_set_state(BLUETOOTH, bluetooth_enabled);
+
+	poll_bios(1);
+
+	return 0;
+}
+
+static struct platform_driver wistron_driver = {
+	.suspend	= wistron_suspend,
+	.resume		= wistron_resume,
+	.driver		= {
+		.name	= "wistron-bios",
+	},
+};
+
+static int __init wb_module_init(void)
+{
+	int err;
+
+	err = select_keymap();
+	if (err)
+		return err;
+
+	err = map_bios();
+	if (err)
+		return err;
+
+	bios_attach();
+	cmos_address = bios_get_cmos_address();
+
+	err = platform_driver_register(&wistron_driver);
+	if (err)
+		goto err_detach_bios;
+
+	wistron_device = platform_device_register_simple("wistron-bios", -1, NULL, 0);
+	if (IS_ERR(wistron_device)) {
+		err = PTR_ERR(wistron_device);
+		goto err_unregister_driver;
+	}
+
+	if (have_wifi) {
+		u16 wifi = bios_get_default_setting(WIFI);
+		if (wifi & 1)
+			wifi_enabled = (wifi & 2) ? 1 : 0;
+		else
+			have_wifi = 0;
+
+		if (have_wifi)
+			bios_set_state(WIFI, wifi_enabled);
+	}
+
+	if (have_bluetooth) {
+		u16 bt = bios_get_default_setting(BLUETOOTH);
+		if (bt & 1)
+			bluetooth_enabled = (bt & 2) ? 1 : 0;
+		else
+			have_bluetooth = 0;
+
+		if (have_bluetooth)
+			bios_set_state(BLUETOOTH, bluetooth_enabled);
+	}
+
+	err = setup_input_dev();
+	if (err)
+		goto err_unregister_device;
+
+	poll_bios(1); /* Flush stale event queue and arm timer */
+
+	return 0;
+
+ err_unregister_device:
+	platform_device_unregister(wistron_device);
+ err_unregister_driver:
+	platform_driver_unregister(&wistron_driver);
+ err_detach_bios:
+	bios_detach();
+	unmap_bios();
+
+	return err;
+}
+
+static void __exit wb_module_exit(void)
+{
+	del_timer_sync(&poll_timer);
+	input_unregister_device(input_dev);
+	platform_device_unregister(wistron_device);
+	platform_driver_unregister(&wistron_driver);
+	bios_detach();
+	unmap_bios();
+}
+
+module_init(wb_module_init);
+module_exit(wb_module_exit);

+ 9 - 3
drivers/input/serio/serio.c

@@ -269,14 +269,20 @@ static struct serio_event *serio_get_event(void)
 	return event;
 	return event;
 }
 }
 
 
-static void serio_handle_events(void)
+static void serio_handle_event(void)
 {
 {
 	struct serio_event *event;
 	struct serio_event *event;
 	struct serio_driver *serio_drv;
 	struct serio_driver *serio_drv;
 
 
 	down(&serio_sem);
 	down(&serio_sem);
 
 
-	while ((event = serio_get_event())) {
+	/*
+	 * Note that we handle only one event here to give swsusp
+	 * a chance to freeze kseriod thread. Serio events should
+	 * be pretty rare so we are not concerned about taking
+	 * performance hit.
+	 */
+	if ((event = serio_get_event())) {
 
 
 		switch (event->type) {
 		switch (event->type) {
 			case SERIO_REGISTER_PORT:
 			case SERIO_REGISTER_PORT:
@@ -368,7 +374,7 @@ static struct serio *serio_get_pending_child(struct serio *parent)
 static int serio_thread(void *nothing)
 static int serio_thread(void *nothing)
 {
 {
 	do {
 	do {
-		serio_handle_events();
+		serio_handle_event();
 		wait_event_interruptible(serio_wait,
 		wait_event_interruptible(serio_wait,
 			kthread_should_stop() || !list_empty(&serio_event_list));
 			kthread_should_stop() || !list_empty(&serio_event_list));
 		try_to_freeze();
 		try_to_freeze();

+ 6 - 6
drivers/isdn/hisax/Kconfig

@@ -110,7 +110,7 @@ config HISAX_16_3
 
 
 config HISAX_TELESPCI
 config HISAX_TELESPCI
 	bool "Teles PCI"
 	bool "Teles PCI"
-	depends on PCI && (BROKEN || !(SPARC64 || PPC))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
 	help
 	help
 	  This enables HiSax support for the Teles PCI.
 	  This enables HiSax support for the Teles PCI.
 	  See <file:Documentation/isdn/README.HiSax> on how to configure it.
 	  See <file:Documentation/isdn/README.HiSax> on how to configure it.
@@ -238,7 +238,7 @@ config HISAX_MIC
 
 
 config HISAX_NETJET
 config HISAX_NETJET
 	bool "NETjet card"
 	bool "NETjet card"
-	depends on PCI && (BROKEN || !(SPARC64 || PPC))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
 	help
 	help
 	  This enables HiSax support for the NetJet from Traverse
 	  This enables HiSax support for the NetJet from Traverse
 	  Technologies.
 	  Technologies.
@@ -249,7 +249,7 @@ config HISAX_NETJET
 
 
 config HISAX_NETJET_U
 config HISAX_NETJET_U
 	bool "NETspider U card"
 	bool "NETspider U card"
-	depends on PCI && (BROKEN || !(SPARC64 || PPC))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
 	help
 	help
 	  This enables HiSax support for the Netspider U interface ISDN card
 	  This enables HiSax support for the Netspider U interface ISDN card
 	  from Traverse Technologies.
 	  from Traverse Technologies.
@@ -317,7 +317,7 @@ config HISAX_GAZEL
 
 
 config HISAX_HFC_PCI
 config HISAX_HFC_PCI
 	bool "HFC PCI-Bus cards"
 	bool "HFC PCI-Bus cards"
-	depends on PCI && (BROKEN || !(SPARC64 || PPC))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
 	help
 	help
 	  This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
 	  This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
 
 
@@ -344,14 +344,14 @@ config HISAX_HFC_SX
 
 
 config HISAX_ENTERNOW_PCI
 config HISAX_ENTERNOW_PCI
 	bool "Formula-n enter:now PCI card"
 	bool "Formula-n enter:now PCI card"
-	depends on PCI && (BROKEN || !(SPARC64 || PPC))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
 	help
 	help
 	  This enables HiSax support for the Formula-n enter:now PCI
 	  This enables HiSax support for the Formula-n enter:now PCI
 	  ISDN card.
 	  ISDN card.
 
 
 config HISAX_AMD7930
 config HISAX_AMD7930
 	bool "Am7930 (EXPERIMENTAL)"
 	bool "Am7930 (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && (SPARC32 || SPARC64)
+	depends on EXPERIMENTAL && SPARC
 	help
 	help
 	  This enables HiSax support for the AMD7930 chips on some SPARCs.
 	  This enables HiSax support for the AMD7930 chips on some SPARCs.
 	  This code is not finished yet.
 	  This code is not finished yet.

+ 1 - 1
drivers/isdn/pcbit/Kconfig

@@ -3,7 +3,7 @@
 #
 #
 config ISDN_DRV_PCBIT
 config ISDN_DRV_PCBIT
 	tristate "PCBIT-D support"
 	tristate "PCBIT-D support"
-	depends on ISDN_I4L && ISA && (BROKEN || !PPC)
+	depends on ISDN_I4L && ISA && (BROKEN || X86)
 	help
 	help
 	  This enables support for the PCBIT ISDN-card.  This card is
 	  This enables support for the PCBIT ISDN-card.  This card is
 	  manufactured in Portugal by Octal.  For running this card,
 	  manufactured in Portugal by Octal.  For running this card,

+ 1 - 1
drivers/media/dvb/cinergyT2/cinergyT2.c

@@ -772,7 +772,7 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
 	input_dev->name = DRIVER_NAME " remote control";
 	input_dev->name = DRIVER_NAME " remote control";
 	input_dev->phys = cinergyt2->phys;
 	input_dev->phys = cinergyt2->phys;
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
-	for (i = 0; ARRAY_SIZE(rc_keys); i += 3)
+	for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3)
 		set_bit(rc_keys[i + 2], input_dev->keybit);
 		set_bit(rc_keys[i + 2], input_dev->keybit);
 	input_dev->keycodesize = 0;
 	input_dev->keycodesize = 0;
 	input_dev->keycodemax = 0;
 	input_dev->keycodemax = 0;

+ 3 - 2
drivers/media/video/ir-kbd-gpio.c

@@ -673,7 +673,6 @@ static int ir_probe(struct device *dev)
 	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
 	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
 		 pci_name(sub->core->pci));
 		 pci_name(sub->core->pci));
 
 
-	ir->sub = sub;
 	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
 	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
 	input_dev->name = ir->name;
 	input_dev->name = ir->name;
 	input_dev->phys = ir->phys;
 	input_dev->phys = ir->phys;
@@ -688,6 +687,9 @@ static int ir_probe(struct device *dev)
 	}
 	}
 	input_dev->cdev.dev = &sub->core->pci->dev;
 	input_dev->cdev.dev = &sub->core->pci->dev;
 
 
+	ir->input = input_dev;
+	ir->sub = sub;
+
 	if (ir->polling) {
 	if (ir->polling) {
 		INIT_WORK(&ir->work, ir_work, ir);
 		INIT_WORK(&ir->work, ir_work, ir);
 		init_timer(&ir->timer);
 		init_timer(&ir->timer);
@@ -708,7 +710,6 @@ static int ir_probe(struct device *dev)
 	/* all done */
 	/* all done */
 	dev_set_drvdata(dev, ir);
 	dev_set_drvdata(dev, ir);
 	input_register_device(ir->input);
 	input_register_device(ir->input);
-	printk(DEVNAME ": %s detected at %s\n",ir->name,ir->phys);
 
 
 	/* the remote isn't as bouncy as a keyboard */
 	/* the remote isn't as bouncy as a keyboard */
 	ir->input->rep[REP_DELAY] = repeat_delay;
 	ir->input->rep[REP_DELAY] = repeat_delay;

+ 2 - 0
drivers/media/video/saa7134/saa7134-input.c

@@ -713,6 +713,8 @@ int saa7134_input_init1(struct saa7134_dev *dev)
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
+	ir->dev = input_dev;
+
 	/* init hardware-specific stuff */
 	/* init hardware-specific stuff */
 	ir->mask_keycode = mask_keycode;
 	ir->mask_keycode = mask_keycode;
 	ir->mask_keydown = mask_keydown;
 	ir->mask_keydown = mask_keydown;

+ 3 - 3
drivers/mtd/maps/ipaq-flash.c

@@ -246,7 +246,7 @@ int __init ipaq_mtd_init(void)
 			ipaq_map[i].size = h3xxx_max_flash_size;
 			ipaq_map[i].size = h3xxx_max_flash_size;
 			ipaq_map[i].set_vpp = h3xxx_set_vpp;
 			ipaq_map[i].set_vpp = h3xxx_set_vpp;
 			ipaq_map[i].phys = cs_phys[i];
 			ipaq_map[i].phys = cs_phys[i];
-			ipaq_map[i].virt = __ioremap(cs_phys[i], 0x04000000, 0, 1);
+			ipaq_map[i].virt = ioremap(cs_phys[i], 0x04000000);
 			if (machine_is_h3100 () || machine_is_h1900())
 			if (machine_is_h3100 () || machine_is_h1900())
 				ipaq_map[i].bankwidth = 2;
 				ipaq_map[i].bankwidth = 2;
 		}
 		}
@@ -280,7 +280,7 @@ int __init ipaq_mtd_init(void)
 		nb_parts = ARRAY_SIZE(jornada_partitions);
 		nb_parts = ARRAY_SIZE(jornada_partitions);
 		ipaq_map[0].size = jornada_max_flash_size;
 		ipaq_map[0].size = jornada_max_flash_size;
 		ipaq_map[0].set_vpp = jornada56x_set_vpp;
 		ipaq_map[0].set_vpp = jornada56x_set_vpp;
-		ipaq_map[0].virt = (__u32)__ioremap(0x0, 0x04000000, 0, 1);
+		ipaq_map[0].virt = (__u32)ioremap(0x0, 0x04000000);
 	}
 	}
 #endif
 #endif
 #ifdef CONFIG_SA1100_JORNADA720
 #ifdef CONFIG_SA1100_JORNADA720
@@ -442,7 +442,7 @@ static int __init h1900_special_case(void)
 	ipaq_map[0].size = 0x80000;
 	ipaq_map[0].size = 0x80000;
 	ipaq_map[0].set_vpp = h3xxx_set_vpp;
 	ipaq_map[0].set_vpp = h3xxx_set_vpp;
 	ipaq_map[0].phys = 0x0;
 	ipaq_map[0].phys = 0x0;
-	ipaq_map[0].virt = __ioremap(0x0, 0x04000000, 0, 1);
+	ipaq_map[0].virt = ioremap(0x0, 0x04000000);
 	ipaq_map[0].bankwidth = 2;
 	ipaq_map[0].bankwidth = 2;
 
 
 	printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt);
 	printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt);

+ 11 - 11
drivers/mtd/maps/ixp2000.c

@@ -159,12 +159,12 @@ static int ixp2000_flash_probe(struct platform_device *dev)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	window_size = dev->resource->end - dev->resource->start + 1;
 	window_size = dev->resource->end - dev->resource->start + 1;
-	dev_info(_dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n",
-			ixp_data->nr_banks, ((u32)window_size >> 20));
+	dev_info(&dev->dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n",
+		 ixp_data->nr_banks, ((u32)window_size >> 20));
 
 
 	if (plat->width != 1) {
 	if (plat->width != 1) {
-		dev_err(_dev, "IXP2000 MTD map only supports 8-bit mode, asking for %d\n",
-				plat->width * 8);
+		dev_err(&dev->dev, "IXP2000 MTD map only supports 8-bit mode, asking for %d\n",
+			plat->width * 8);
 		return -EIO;
 		return -EIO;
 	}
 	}
 
 
@@ -202,7 +202,7 @@ static int ixp2000_flash_probe(struct platform_device *dev)
 			dev->resource->end - dev->resource->start + 1,
 			dev->resource->end - dev->resource->start + 1,
 			dev->dev.bus_id);
 			dev->dev.bus_id);
 	if (!info->res) {
 	if (!info->res) {
-		dev_err(_dev, "Could not reserve memory region\n");
+		dev_err(&dev->dev, "Could not reserve memory region\n");
 		err = -ENOMEM;
 		err = -ENOMEM;
 		goto Error;
 		goto Error;
 	}
 	}
@@ -210,7 +210,7 @@ static int ixp2000_flash_probe(struct platform_device *dev)
 	info->map.map_priv_1 = (unsigned long) ioremap(dev->resource->start,
 	info->map.map_priv_1 = (unsigned long) ioremap(dev->resource->start,
 			    	dev->resource->end - dev->resource->start + 1);
 			    	dev->resource->end - dev->resource->start + 1);
 	if (!info->map.map_priv_1) {
 	if (!info->map.map_priv_1) {
-		dev_err(_dev, "Failed to ioremap flash region\n");
+		dev_err(&dev->dev, "Failed to ioremap flash region\n");
 		err = -EIO;
 		err = -EIO;
 		goto Error;
 		goto Error;
 	}
 	}
@@ -221,13 +221,13 @@ static int ixp2000_flash_probe(struct platform_device *dev)
 	 */
 	 */
 
 
 	erratum44_workaround = ixp2000_has_broken_slowport();
 	erratum44_workaround = ixp2000_has_broken_slowport();
-	dev_info(_dev, "Erratum 44 workaround %s\n",
+	dev_info(&dev->dev, "Erratum 44 workaround %s\n",
 	       erratum44_workaround ? "enabled" : "disabled");
 	       erratum44_workaround ? "enabled" : "disabled");
 #endif
 #endif
 
 
 	info->mtd = do_map_probe(plat->map_name, &info->map);
 	info->mtd = do_map_probe(plat->map_name, &info->map);
 	if (!info->mtd) {
 	if (!info->mtd) {
-		dev_err(_dev, "map_probe failed\n");
+		dev_err(&dev->dev, "map_probe failed\n");
 		err = -ENXIO;
 		err = -ENXIO;
 		goto Error;
 		goto Error;
 	}
 	}
@@ -237,7 +237,7 @@ static int ixp2000_flash_probe(struct platform_device *dev)
 	if (err > 0) {
 	if (err > 0) {
 		err = add_mtd_partitions(info->mtd, info->partitions, err);
 		err = add_mtd_partitions(info->mtd, info->partitions, err);
 		if(err)
 		if(err)
-			dev_err(_dev, "Could not parse partitions\n");
+			dev_err(&dev->dev, "Could not parse partitions\n");
 	}
 	}
 
 
 	if (err)
 	if (err)
@@ -251,8 +251,8 @@ Error:
 }
 }
 
 
 static struct platform_driver ixp2000_flash_driver = {
 static struct platform_driver ixp2000_flash_driver = {
-	.probe		= &ixp2000_flash_probe,
-	.remove		= &ixp2000_flash_remove
+	.probe		= ixp2000_flash_probe,
+	.remove		= ixp2000_flash_remove,
 	.driver		= {
 	.driver		= {
 		.name	= "IXP2000-Flash",
 		.name	= "IXP2000-Flash",
 	},
 	},

+ 1 - 1
drivers/mtd/nand/h1910.c

@@ -112,7 +112,7 @@ static int __init h1910_init (void)
 	if (!machine_is_h1900())
 	if (!machine_is_h1900())
 		return -ENODEV;
 		return -ENODEV;
 
 
-	nandaddr = __ioremap(0x08000000, 0x1000, 0, 1);
+	nandaddr = ioremap(0x08000000, 0x1000);
 	if (!nandaddr) {
 	if (!nandaddr) {
 		printk("Failed to ioremap nand flash.\n");
 		printk("Failed to ioremap nand flash.\n");
 		return -ENOMEM;
 		return -ENOMEM;

+ 1 - 0
drivers/net/au1000_eth.c

@@ -32,6 +32,7 @@
  * 
  * 
  */
  */
 
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/sched.h>

+ 257 - 18
drivers/net/e100.c

@@ -156,7 +156,7 @@
 
 
 #define DRV_NAME		"e100"
 #define DRV_NAME		"e100"
 #define DRV_EXT		"-NAPI"
 #define DRV_EXT		"-NAPI"
-#define DRV_VERSION		"3.4.14-k2"DRV_EXT
+#define DRV_VERSION		"3.4.14-k4"DRV_EXT
 #define DRV_DESCRIPTION		"Intel(R) PRO/100 Network Driver"
 #define DRV_DESCRIPTION		"Intel(R) PRO/100 Network Driver"
 #define DRV_COPYRIGHT		"Copyright(c) 1999-2005 Intel Corporation"
 #define DRV_COPYRIGHT		"Copyright(c) 1999-2005 Intel Corporation"
 #define PFX			DRV_NAME ": "
 #define PFX			DRV_NAME ": "
@@ -903,8 +903,8 @@ static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
 
 
 static void e100_get_defaults(struct nic *nic)
 static void e100_get_defaults(struct nic *nic)
 {
 {
-	struct param_range rfds = { .min = 16, .max = 256, .count = 64 };
-	struct param_range cbs  = { .min = 64, .max = 256, .count = 64 };
+	struct param_range rfds = { .min = 16, .max = 256, .count = 256 };
+	struct param_range cbs  = { .min = 64, .max = 256, .count = 128 };
 
 
 	pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
 	pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
 	/* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
 	/* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
@@ -1007,25 +1007,264 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
 		c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
 		c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
 }
 }
 
 
+/********************************************************/
+/*  Micro code for 8086:1229 Rev 8                      */
+/********************************************************/
+
+/*  Parameter values for the D101M B-step  */
+#define D101M_CPUSAVER_TIMER_DWORD		78
+#define D101M_CPUSAVER_BUNDLE_DWORD		65
+#define D101M_CPUSAVER_MIN_SIZE_DWORD		126
+
+#define D101M_B_RCVBUNDLE_UCODE \
+{\
+0x00550215, 0xFFFF0437, 0xFFFFFFFF, 0x06A70789, 0xFFFFFFFF, 0x0558FFFF, \
+0x000C0001, 0x00101312, 0x000C0008, 0x00380216, \
+0x0010009C, 0x00204056, 0x002380CC, 0x00380056, \
+0x0010009C, 0x00244C0B, 0x00000800, 0x00124818, \
+0x00380438, 0x00000000, 0x00140000, 0x00380555, \
+0x00308000, 0x00100662, 0x00100561, 0x000E0408, \
+0x00134861, 0x000C0002, 0x00103093, 0x00308000, \
+0x00100624, 0x00100561, 0x000E0408, 0x00100861, \
+0x000C007E, 0x00222C21, 0x000C0002, 0x00103093, \
+0x00380C7A, 0x00080000, 0x00103090, 0x00380C7A, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x0010009C, 0x00244C2D, 0x00010004, 0x00041000, \
+0x003A0437, 0x00044010, 0x0038078A, 0x00000000, \
+0x00100099, 0x00206C7A, 0x0010009C, 0x00244C48, \
+0x00130824, 0x000C0001, 0x00101213, 0x00260C75, \
+0x00041000, 0x00010004, 0x00130826, 0x000C0006, \
+0x002206A8, 0x0013C926, 0x00101313, 0x003806A8, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00080600, 0x00101B10, 0x00050004, 0x00100826, \
+0x00101210, 0x00380C34, 0x00000000, 0x00000000, \
+0x0021155B, 0x00100099, 0x00206559, 0x0010009C, \
+0x00244559, 0x00130836, 0x000C0000, 0x00220C62, \
+0x000C0001, 0x00101B13, 0x00229C0E, 0x00210C0E, \
+0x00226C0E, 0x00216C0E, 0x0022FC0E, 0x00215C0E, \
+0x00214C0E, 0x00380555, 0x00010004, 0x00041000, \
+0x00278C67, 0x00040800, 0x00018100, 0x003A0437, \
+0x00130826, 0x000C0001, 0x00220559, 0x00101313, \
+0x00380559, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00130831, 0x0010090B, 0x00124813, \
+0x000CFF80, 0x002606AB, 0x00041000, 0x00010004, \
+0x003806A8, 0x00000000, 0x00000000, 0x00000000, \
+}
+
+/********************************************************/
+/*  Micro code for 8086:1229 Rev 9                      */
+/********************************************************/
+
+/*  Parameter values for the D101S  */
+#define D101S_CPUSAVER_TIMER_DWORD		78
+#define D101S_CPUSAVER_BUNDLE_DWORD		67
+#define D101S_CPUSAVER_MIN_SIZE_DWORD		128
+
+#define D101S_RCVBUNDLE_UCODE \
+{\
+0x00550242, 0xFFFF047E, 0xFFFFFFFF, 0x06FF0818, 0xFFFFFFFF, 0x05A6FFFF, \
+0x000C0001, 0x00101312, 0x000C0008, 0x00380243, \
+0x0010009C, 0x00204056, 0x002380D0, 0x00380056, \
+0x0010009C, 0x00244F8B, 0x00000800, 0x00124818, \
+0x0038047F, 0x00000000, 0x00140000, 0x003805A3, \
+0x00308000, 0x00100610, 0x00100561, 0x000E0408, \
+0x00134861, 0x000C0002, 0x00103093, 0x00308000, \
+0x00100624, 0x00100561, 0x000E0408, 0x00100861, \
+0x000C007E, 0x00222FA1, 0x000C0002, 0x00103093, \
+0x00380F90, 0x00080000, 0x00103090, 0x00380F90, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x0010009C, 0x00244FAD, 0x00010004, 0x00041000, \
+0x003A047E, 0x00044010, 0x00380819, 0x00000000, \
+0x00100099, 0x00206FFD, 0x0010009A, 0x0020AFFD, \
+0x0010009C, 0x00244FC8, 0x00130824, 0x000C0001, \
+0x00101213, 0x00260FF7, 0x00041000, 0x00010004, \
+0x00130826, 0x000C0006, 0x00220700, 0x0013C926, \
+0x00101313, 0x00380700, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00080600, 0x00101B10, 0x00050004, 0x00100826, \
+0x00101210, 0x00380FB6, 0x00000000, 0x00000000, \
+0x002115A9, 0x00100099, 0x002065A7, 0x0010009A, \
+0x0020A5A7, 0x0010009C, 0x002445A7, 0x00130836, \
+0x000C0000, 0x00220FE4, 0x000C0001, 0x00101B13, \
+0x00229F8E, 0x00210F8E, 0x00226F8E, 0x00216F8E, \
+0x0022FF8E, 0x00215F8E, 0x00214F8E, 0x003805A3, \
+0x00010004, 0x00041000, 0x00278FE9, 0x00040800, \
+0x00018100, 0x003A047E, 0x00130826, 0x000C0001, \
+0x002205A7, 0x00101313, 0x003805A7, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00130831, \
+0x0010090B, 0x00124813, 0x000CFF80, 0x00260703, \
+0x00041000, 0x00010004, 0x00380700  \
+}
+
+/********************************************************/
+/*  Micro code for the 8086:1229 Rev F/10               */
+/********************************************************/
+
+/*  Parameter values for the D102 E-step  */
+#define D102_E_CPUSAVER_TIMER_DWORD		42
+#define D102_E_CPUSAVER_BUNDLE_DWORD		54
+#define D102_E_CPUSAVER_MIN_SIZE_DWORD		46
+
+#define     D102_E_RCVBUNDLE_UCODE \
+{\
+0x007D028F, 0x0E4204F9, 0x14ED0C85, 0x14FA14E9, 0x0EF70E36, 0x1FFF1FFF, \
+0x00E014B9, 0x00000000, 0x00000000, 0x00000000, \
+0x00E014BD, 0x00000000, 0x00000000, 0x00000000, \
+0x00E014D5, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00E014C1, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00E014C8, 0x00000000, 0x00000000, 0x00000000, \
+0x00200600, 0x00E014EE, 0x00000000, 0x00000000, \
+0x0030FF80, 0x00940E46, 0x00038200, 0x00102000, \
+0x00E00E43, 0x00000000, 0x00000000, 0x00000000, \
+0x00300006, 0x00E014FB, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000, \
+0x00906EFD, 0x00900EFD, 0x00E00EF8, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+}
+
 static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb)
 static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb)
 {
 {
-	int i;
-	static const u32 ucode[UCODE_SIZE] = {
-		/* NFS packets are misinterpreted as TCO packets and
-		 * incorrectly routed to the BMC over SMBus.  This
-		 * microcode patch checks the fragmented IP bit in the
-		 * NFS/UDP header to distinguish between NFS and TCO. */
-		0x0EF70E36, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF,
-		0x1FFF1FFF, 0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000,
-		0x00906EFD, 0x00900EFD,	0x00E00EF8,
-	};
-
-	if(nic->mac == mac_82551_F || nic->mac == mac_82551_10) {
-		for(i = 0; i < UCODE_SIZE; i++)
+/* *INDENT-OFF* */
+	static struct {
+		u32 ucode[UCODE_SIZE + 1];
+		u8 mac;
+		u8 timer_dword;
+		u8 bundle_dword;
+		u8 min_size_dword;
+	} ucode_opts[] = {
+		{ D101M_B_RCVBUNDLE_UCODE,
+		  mac_82559_D101M,
+		  D101M_CPUSAVER_TIMER_DWORD,
+		  D101M_CPUSAVER_BUNDLE_DWORD,
+		  D101M_CPUSAVER_MIN_SIZE_DWORD },
+		{ D101S_RCVBUNDLE_UCODE,
+		  mac_82559_D101S,
+		  D101S_CPUSAVER_TIMER_DWORD,
+		  D101S_CPUSAVER_BUNDLE_DWORD,
+		  D101S_CPUSAVER_MIN_SIZE_DWORD },
+		{ D102_E_RCVBUNDLE_UCODE,
+		  mac_82551_F,
+		  D102_E_CPUSAVER_TIMER_DWORD,
+		  D102_E_CPUSAVER_BUNDLE_DWORD,
+		  D102_E_CPUSAVER_MIN_SIZE_DWORD },
+		{ D102_E_RCVBUNDLE_UCODE,
+		  mac_82551_10,
+		  D102_E_CPUSAVER_TIMER_DWORD,
+		  D102_E_CPUSAVER_BUNDLE_DWORD,
+		  D102_E_CPUSAVER_MIN_SIZE_DWORD },
+		{ {0}, 0, 0, 0, 0}
+	}, *opts;
+/* *INDENT-ON* */
+
+/*************************************************************************
+*  CPUSaver parameters
+*
+*  All CPUSaver parameters are 16-bit literals that are part of a
+*  "move immediate value" instruction.  By changing the value of
+*  the literal in the instruction before the code is loaded, the
+*  driver can change the algorithm.
+*
+*  INTDELAY - This loads the dead-man timer with its inital value.
+*    When this timer expires the interrupt is asserted, and the 
+*    timer is reset each time a new packet is received.  (see
+*    BUNDLEMAX below to set the limit on number of chained packets)
+*    The current default is 0x600 or 1536.  Experiments show that
+*    the value should probably stay within the 0x200 - 0x1000.
+*
+*  BUNDLEMAX - 
+*    This sets the maximum number of frames that will be bundled.  In
+*    some situations, such as the TCP windowing algorithm, it may be
+*    better to limit the growth of the bundle size than let it go as
+*    high as it can, because that could cause too much added latency.
+*    The default is six, because this is the number of packets in the
+*    default TCP window size.  A value of 1 would make CPUSaver indicate
+*    an interrupt for every frame received.  If you do not want to put
+*    a limit on the bundle size, set this value to xFFFF.
+*
+*  BUNDLESMALL - 
+*    This contains a bit-mask describing the minimum size frame that
+*    will be bundled.  The default masks the lower 7 bits, which means
+*    that any frame less than 128 bytes in length will not be bundled,
+*    but will instead immediately generate an interrupt.  This does
+*    not affect the current bundle in any way.  Any frame that is 128
+*    bytes or large will be bundled normally.  This feature is meant
+*    to provide immediate indication of ACK frames in a TCP environment.
+*    Customers were seeing poor performance when a machine with CPUSaver
+*    enabled was sending but not receiving.  The delay introduced when
+*    the ACKs were received was enough to reduce total throughput, because
+*    the sender would sit idle until the ACK was finally seen.
+*
+*    The current default is 0xFF80, which masks out the lower 7 bits.
+*    This means that any frame which is x7F (127) bytes or smaller
+*    will cause an immediate interrupt.  Because this value must be a 
+*    bit mask, there are only a few valid values that can be used.  To
+*    turn this feature off, the driver can write the value xFFFF to the
+*    lower word of this instruction (in the same way that the other
+*    parameters are used).  Likewise, a value of 0xF800 (2047) would
+*    cause an interrupt to be generated for every frame, because all
+*    standard Ethernet frames are <= 2047 bytes in length.
+*************************************************************************/
+
+/* if you wish to disable the ucode functionality, while maintaining the 
+ * workarounds it provides, set the following defines to:
+ * BUNDLESMALL 0
+ * BUNDLEMAX 1
+ * INTDELAY 1
+ */
+#define BUNDLESMALL 1
+#define BUNDLEMAX (u16)6
+#define INTDELAY (u16)1536 /* 0x600 */
+
+	/* do not load u-code for ICH devices */
+	if (nic->flags & ich)
+		goto noloaducode;
+
+	/* Search for ucode match against h/w rev_id */
+	for (opts = ucode_opts; opts->mac; opts++) {
+		int i;
+		u32 *ucode = opts->ucode;
+		if (nic->mac != opts->mac)
+			continue;
+
+		/* Insert user-tunable settings */
+		ucode[opts->timer_dword] &= 0xFFFF0000;
+		ucode[opts->timer_dword] |= INTDELAY;
+		ucode[opts->bundle_dword] &= 0xFFFF0000;
+		ucode[opts->bundle_dword] |= BUNDLEMAX;
+		ucode[opts->min_size_dword] &= 0xFFFF0000;
+		ucode[opts->min_size_dword] |= (BUNDLESMALL) ? 0xFFFF : 0xFF80;
+
+		for (i = 0; i < UCODE_SIZE; i++)
 			cb->u.ucode[i] = cpu_to_le32(ucode[i]);
 			cb->u.ucode[i] = cpu_to_le32(ucode[i]);
 		cb->command = cpu_to_le16(cb_ucode);
 		cb->command = cpu_to_le16(cb_ucode);
-	} else
-		cb->command = cpu_to_le16(cb_nop);
+		return;
+	}
+
+noloaducode:
+	cb->command = cpu_to_le16(cb_nop);
 }
 }
 
 
 static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,
 static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,

+ 1 - 1
drivers/net/fec_8xx/Kconfig

@@ -1,6 +1,6 @@
 config FEC_8XX
 config FEC_8XX
 	tristate "Motorola 8xx FEC driver"
 	tristate "Motorola 8xx FEC driver"
-	depends on NET_ETHERNET && FEC
+	depends on NET_ETHERNET && 8xx
 	select MII
 	select MII
 
 
 config FEC_8XX_GENERIC_PHY
 config FEC_8XX_GENERIC_PHY

+ 1 - 1
drivers/net/ioc3-eth.c

@@ -1360,7 +1360,7 @@ static struct pci_driver ioc3_driver = {
 
 
 static int __init ioc3_init_module(void)
 static int __init ioc3_init_module(void)
 {
 {
-	return pci_module_init(&ioc3_driver);
+	return pci_register_driver(&ioc3_driver);
 }
 }
 
 
 static void __exit ioc3_cleanup_module(void)
 static void __exit ioc3_cleanup_module(void)

+ 2 - 4
drivers/net/r8169.c

@@ -1346,10 +1346,8 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
 	} else {
 	} else {
 		if (netif_msg_probe(tp)) {
 		if (netif_msg_probe(tp)) {
 			printk(KERN_ERR PFX
 			printk(KERN_ERR PFX
-			       "Cannot find PowerManagement capability. "
-			       "Aborting.\n");
+			       "PowerManagement capability not found.\n");
 		}
 		}
-		goto err_out_mwi;
 	}
 	}
 
 
 	/* make sure PCI base addr 1 is MMIO */
 	/* make sure PCI base addr 1 is MMIO */
@@ -2516,7 +2514,7 @@ rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
 	} while (boguscnt > 0);
 	} while (boguscnt > 0);
 
 
 	if (boguscnt <= 0) {
 	if (boguscnt <= 0) {
-		if (net_ratelimit() && netif_msg_intr(tp)) {
+		if (netif_msg_intr(tp) && net_ratelimit() ) {
 			printk(KERN_WARNING
 			printk(KERN_WARNING
 			       "%s: Too much work at interrupt!\n", dev->name);
 			       "%s: Too much work at interrupt!\n", dev->name);
 		}
 		}

+ 25 - 11
drivers/net/saa9730.h

@@ -1,6 +1,7 @@
 /*
 /*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2000, 2005  MIPS Technologies, Inc.  All rights reserved.
+ *	Authors: Carsten Langgaard <carstenl@mips.com>
+ *		 Maciej W. Rozycki <macro@mips.com>
  *
  *
  * ########################################################################
  * ########################################################################
  *
  *
@@ -265,6 +266,7 @@
 
 
 /* The SAA9730 (LAN) controller register map, as seen via the PCI-bus. */
 /* The SAA9730 (LAN) controller register map, as seen via the PCI-bus. */
 #define SAA9730_LAN_REGS_ADDR   0x20400
 #define SAA9730_LAN_REGS_ADDR   0x20400
+#define SAA9730_LAN_REGS_SIZE   0x00400
 
 
 struct lan_saa9730_regmap {
 struct lan_saa9730_regmap {
 	volatile unsigned int TxBuffA;			/* 0x20400 */
 	volatile unsigned int TxBuffA;			/* 0x20400 */
@@ -309,6 +311,7 @@ typedef volatile struct lan_saa9730_regmap t_lan_saa9730_regmap;
 
 
 /* The SAA9730 (EVM) controller register map, as seen via the PCI-bus. */
 /* The SAA9730 (EVM) controller register map, as seen via the PCI-bus. */
 #define SAA9730_EVM_REGS_ADDR   0x02000
 #define SAA9730_EVM_REGS_ADDR   0x02000
+#define SAA9730_EVM_REGS_SIZE   0x00400
 
 
 struct evm_saa9730_regmap {
 struct evm_saa9730_regmap {
 	volatile unsigned int InterruptStatus1;		/* 0x2000 */
 	volatile unsigned int InterruptStatus1;		/* 0x2000 */
@@ -329,16 +332,32 @@ typedef volatile struct evm_saa9730_regmap t_evm_saa9730_regmap;
 
 
 
 
 struct lan_saa9730_private {
 struct lan_saa9730_private {
+	/*
+	 * Rx/Tx packet buffers.
+	 * The Rx and Tx packets must be PACKET_SIZE aligned.
+	 */
+	void		*buffer_start;
+	unsigned int	buffer_size;
+
+	/*
+	 * DMA address of beginning of this object, returned
+	 * by pci_alloc_consistent().
+	 */
+	dma_addr_t	dma_addr;
+
+	/* Pointer to the associated pci device structure */
+	struct pci_dev	*pci_dev;
+
 	/* Pointer for the SAA9730 LAN controller register set. */
 	/* Pointer for the SAA9730 LAN controller register set. */
 	t_lan_saa9730_regmap *lan_saa9730_regs;
 	t_lan_saa9730_regmap *lan_saa9730_regs;
 
 
 	/* Pointer to the SAA9730 EVM register. */
 	/* Pointer to the SAA9730 EVM register. */
 	t_evm_saa9730_regmap *evm_saa9730_regs;
 	t_evm_saa9730_regmap *evm_saa9730_regs;
 
 
-	/* TRUE if the next buffer to write is RxBuffA,  FALSE if RxBuffB. */
-	unsigned char NextRcvToUseIsA;
 	/* Rcv buffer Index. */
 	/* Rcv buffer Index. */
 	unsigned char NextRcvPacketIndex;
 	unsigned char NextRcvPacketIndex;
+	/* Next buffer index. */
+	unsigned char NextRcvBufferIndex;
 
 
 	/* Index of next packet to use in that buffer. */
 	/* Index of next packet to use in that buffer. */
 	unsigned char NextTxmPacketIndex;
 	unsigned char NextTxmPacketIndex;
@@ -353,13 +372,8 @@ struct lan_saa9730_private {
 	unsigned char DmaRcvPackets;
 	unsigned char DmaRcvPackets;
 	unsigned char DmaTxmPackets;
 	unsigned char DmaTxmPackets;
 
 
-	unsigned char RcvAIndex;	/* index into RcvBufferSpace[] for Blk A */
-	unsigned char RcvBIndex;	/* index into RcvBufferSpace[] for Blk B */
-
-	unsigned int
-	    TxmBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_TXM_Q_SIZE];
-	unsigned int
-	    RcvBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_RCV_Q_SIZE];
+	void	      *TxmBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_TXM_Q_SIZE];
+	void	      *RcvBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_RCV_Q_SIZE];
 	unsigned int TxBufferFree[LAN_SAA9730_BUFFERS];
 	unsigned int TxBufferFree[LAN_SAA9730_BUFFERS];
 
 
 	unsigned char PhysicalAddress[LAN_SAA9730_CAM_ENTRIES][6];
 	unsigned char PhysicalAddress[LAN_SAA9730_CAM_ENTRIES][6];

+ 13 - 4
drivers/net/smc91x.c

@@ -154,6 +154,12 @@ MODULE_LICENSE("GPL");
  */
  */
 #define MEMORY_WAIT_TIME	16
 #define MEMORY_WAIT_TIME	16
 
 
+/*
+ * The maximum number of processing loops allowed for each call to the
+ * IRQ handler.  
+ */
+#define MAX_IRQ_LOOPS		8
+
 /*
 /*
  * This selects whether TX packets are sent one by one to the SMC91x internal
  * This selects whether TX packets are sent one by one to the SMC91x internal
  * memory and throttled until transmission completes.  This may prevent
  * memory and throttled until transmission completes.  This may prevent
@@ -684,7 +690,6 @@ static void smc_hardware_send_pkt(unsigned long data)
 
 
 	/* queue the packet for TX */
 	/* queue the packet for TX */
 	SMC_SET_MMU_CMD(MC_ENQUEUE);
 	SMC_SET_MMU_CMD(MC_ENQUEUE);
-	SMC_ACK_INT(IM_TX_EMPTY_INT);
 	smc_special_unlock(&lp->lock);
 	smc_special_unlock(&lp->lock);
 
 
 	dev->trans_start = jiffies;
 	dev->trans_start = jiffies;
@@ -1207,6 +1212,7 @@ static void smc_phy_configure(void *data)
 	smc_phy_check_media(dev, 1);
 	smc_phy_check_media(dev, 1);
 
 
 smc_phy_configure_exit:
 smc_phy_configure_exit:
+	SMC_SELECT_BANK(2);
 	spin_unlock_irq(&lp->lock);
 	spin_unlock_irq(&lp->lock);
 	lp->work_pending = 0;
 	lp->work_pending = 0;
 }
 }
@@ -1305,7 +1311,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 	SMC_SET_INT_MASK(0);
 	SMC_SET_INT_MASK(0);
 
 
 	/* set a timeout value, so I don't stay here forever */
 	/* set a timeout value, so I don't stay here forever */
-	timeout = 8;
+	timeout = MAX_IRQ_LOOPS;
 
 
 	do {
 	do {
 		status = SMC_GET_INT();
 		status = SMC_GET_INT();
@@ -1372,10 +1378,13 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 	/* restore register states */
 	/* restore register states */
 	SMC_SET_PTR(saved_pointer);
 	SMC_SET_PTR(saved_pointer);
 	SMC_SET_INT_MASK(mask);
 	SMC_SET_INT_MASK(mask);
-
 	spin_unlock(&lp->lock);
 	spin_unlock(&lp->lock);
 
 
-	DBG(3, "%s: Interrupt done (%d loops)\n", dev->name, 8-timeout);
+	if (timeout == MAX_IRQ_LOOPS)
+		PRINTK("%s: spurious interrupt (mask = 0x%02x)\n",
+		       dev->name, mask);
+	DBG(3, "%s: Interrupt done (%d loops)\n",
+	       dev->name, MAX_IRQ_LOOPS - timeout);
 
 
 	/*
 	/*
 	 * We return IRQ_HANDLED unconditionally here even if there was
 	 * We return IRQ_HANDLED unconditionally here even if there was

+ 6 - 0
drivers/net/wan/hdlc_cisco.c

@@ -192,7 +192,9 @@ static int cisco_rx(struct sk_buff *skb)
 					       "uptime %ud%uh%um%us)\n",
 					       "uptime %ud%uh%um%us)\n",
 					       dev->name, days, hrs,
 					       dev->name, days, hrs,
 					       min, sec);
 					       min, sec);
+#if 0
 					netif_carrier_on(dev);
 					netif_carrier_on(dev);
+#endif
 					hdlc->state.cisco.up = 1;
 					hdlc->state.cisco.up = 1;
 				}
 				}
 			}
 			}
@@ -225,7 +227,9 @@ static void cisco_timer(unsigned long arg)
 		       hdlc->state.cisco.settings.timeout * HZ)) {
 		       hdlc->state.cisco.settings.timeout * HZ)) {
 		hdlc->state.cisco.up = 0;
 		hdlc->state.cisco.up = 0;
 		printk(KERN_INFO "%s: Link down\n", dev->name);
 		printk(KERN_INFO "%s: Link down\n", dev->name);
+#if 0
 		netif_carrier_off(dev);
 		netif_carrier_off(dev);
+#endif
 	}
 	}
 
 
 	cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ,
 	cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ,
@@ -261,8 +265,10 @@ static void cisco_stop(struct net_device *dev)
 {
 {
 	hdlc_device *hdlc = dev_to_hdlc(dev);
 	hdlc_device *hdlc = dev_to_hdlc(dev);
 	del_timer_sync(&hdlc->state.cisco.timer);
 	del_timer_sync(&hdlc->state.cisco.timer);
+#if 0
 	if (netif_carrier_ok(dev))
 	if (netif_carrier_ok(dev))
 		netif_carrier_off(dev);
 		netif_carrier_off(dev);
+#endif
 	hdlc->state.cisco.up = 0;
 	hdlc->state.cisco.up = 0;
 	hdlc->state.cisco.request_sent = 0;
 	hdlc->state.cisco.request_sent = 0;
 }
 }

+ 4 - 0
drivers/net/wan/hdlc_fr.c

@@ -545,8 +545,10 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
 
 
 	hdlc->state.fr.reliable = reliable;
 	hdlc->state.fr.reliable = reliable;
 	if (reliable) {
 	if (reliable) {
+#if 0
 		if (!netif_carrier_ok(dev))
 		if (!netif_carrier_ok(dev))
 			netif_carrier_on(dev);
 			netif_carrier_on(dev);
+#endif
 
 
 		hdlc->state.fr.n391cnt = 0; /* Request full status */
 		hdlc->state.fr.n391cnt = 0; /* Request full status */
 		hdlc->state.fr.dce_changed = 1;
 		hdlc->state.fr.dce_changed = 1;
@@ -560,8 +562,10 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
 			}
 			}
 		}
 		}
 	} else {
 	} else {
+#if 0
 		if (netif_carrier_ok(dev))
 		if (netif_carrier_ok(dev))
 			netif_carrier_off(dev);
 			netif_carrier_off(dev);
+#endif
 
 
 		while (pvc) {		/* Deactivate all PVCs */
 		while (pvc) {		/* Deactivate all PVCs */
 			pvc_carrier(0, pvc);
 			pvc_carrier(0, pvc);

+ 6 - 0
drivers/net/wan/hdlc_generic.c

@@ -79,11 +79,13 @@ static void __hdlc_set_carrier_on(struct net_device *dev)
 	hdlc_device *hdlc = dev_to_hdlc(dev);
 	hdlc_device *hdlc = dev_to_hdlc(dev);
 	if (hdlc->proto.start)
 	if (hdlc->proto.start)
 		return hdlc->proto.start(dev);
 		return hdlc->proto.start(dev);
+#if 0
 #ifdef DEBUG_LINK
 #ifdef DEBUG_LINK
 	if (netif_carrier_ok(dev))
 	if (netif_carrier_ok(dev))
 		printk(KERN_ERR "hdlc_set_carrier_on(): already on\n");
 		printk(KERN_ERR "hdlc_set_carrier_on(): already on\n");
 #endif
 #endif
 	netif_carrier_on(dev);
 	netif_carrier_on(dev);
+#endif
 }
 }
 
 
 
 
@@ -94,11 +96,13 @@ static void __hdlc_set_carrier_off(struct net_device *dev)
 	if (hdlc->proto.stop)
 	if (hdlc->proto.stop)
 		return hdlc->proto.stop(dev);
 		return hdlc->proto.stop(dev);
 
 
+#if 0
 #ifdef DEBUG_LINK
 #ifdef DEBUG_LINK
 	if (!netif_carrier_ok(dev))
 	if (!netif_carrier_ok(dev))
 		printk(KERN_ERR "hdlc_set_carrier_off(): already off\n");
 		printk(KERN_ERR "hdlc_set_carrier_off(): already off\n");
 #endif
 #endif
 	netif_carrier_off(dev);
 	netif_carrier_off(dev);
+#endif
 }
 }
 
 
 
 
@@ -294,8 +298,10 @@ int register_hdlc_device(struct net_device *dev)
 	if (result != 0)
 	if (result != 0)
 		return -EIO;
 		return -EIO;
 
 
+#if 0
 	if (netif_carrier_ok(dev))
 	if (netif_carrier_ok(dev))
 		netif_carrier_off(dev); /* no carrier until DCD goes up */
 		netif_carrier_off(dev); /* no carrier until DCD goes up */
+#endif
 
 
 	return 0;
 	return 0;
 }
 }

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно